pyfemtet 0.4.9__py3-none-any.whl → 0.4.11__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/opt/_femopt.py +9 -3
- pyfemtet/opt/femprj_sample/wat_ex14_parametric_parallel.py +66 -0
- pyfemtet/opt/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py +64 -0
- pyfemtet/opt/interface/_femtet.py +32 -10
- pyfemtet/opt/interface/_femtet_parametric.py +5 -25
- pyfemtet/opt/opt/_base.py +9 -1
- pyfemtet/opt/opt/_optuna.py +4 -0
- pyfemtet/opt/visualization/__init__.py +0 -7
- pyfemtet/opt/visualization/_create_wrapped_components.py +93 -0
- pyfemtet/opt/visualization/base.py +254 -0
- pyfemtet/opt/visualization/complex_components/__init__.py +0 -0
- pyfemtet/opt/visualization/complex_components/alert_region.py +71 -0
- pyfemtet/opt/visualization/complex_components/control_femtet.py +195 -0
- pyfemtet/opt/visualization/{_graphs.py → complex_components/main_figure_creator.py} +13 -49
- pyfemtet/opt/visualization/complex_components/main_graph.py +263 -0
- pyfemtet/opt/visualization/process_monitor/__init__.py +0 -0
- pyfemtet/opt/visualization/process_monitor/application.py +201 -0
- pyfemtet/opt/visualization/process_monitor/pages.py +276 -0
- pyfemtet/opt/visualization/result_viewer/.gitignore +1 -0
- pyfemtet/opt/visualization/result_viewer/__init__.py +0 -0
- pyfemtet/opt/visualization/result_viewer/application.py +44 -0
- pyfemtet/opt/visualization/result_viewer/pages.py +692 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/tutorial.csv +18 -0
- 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 +81 -0
- 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 +28 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_heatflow_el.csv +22 -0
- 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_trial1.pdt +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_trial10.pdt +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_trial2.pdt +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_trial3.pdt +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_trial4.pdt +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_trial5.pdt +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_trial6.pdt +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_trial7.pdt +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_trial8.pdt +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.Results/Ex14_trial9.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.femprj +0 -0
- pyfemtet/opt/visualization/wrapped_components/__init__.py +0 -0
- pyfemtet/opt/visualization/wrapped_components/dbc.py +1518 -0
- pyfemtet/opt/visualization/wrapped_components/dcc.py +609 -0
- pyfemtet/opt/visualization/wrapped_components/html.py +3570 -0
- pyfemtet/opt/visualization/wrapped_components/str_enum.py +43 -0
- {pyfemtet-0.4.9.dist-info → pyfemtet-0.4.11.dist-info}/METADATA +1 -1
- pyfemtet-0.4.11.dist-info/RECORD +136 -0
- {pyfemtet-0.4.9.dist-info → pyfemtet-0.4.11.dist-info}/entry_points.txt +1 -1
- pyfemtet/opt/visualization/_monitor.py +0 -1227
- pyfemtet/opt/visualization/result_viewer.py +0 -13
- pyfemtet-0.4.9.dist-info/RECORD +0 -81
- {pyfemtet-0.4.9.dist-info → pyfemtet-0.4.11.dist-info}/LICENSE +0 -0
- {pyfemtet-0.4.9.dist-info → pyfemtet-0.4.11.dist-info}/WHEEL +0 -0
pyfemtet/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.4.
|
|
1
|
+
__version__ = "0.4.11"
|
pyfemtet/opt/_femopt.py
CHANGED
|
@@ -13,7 +13,7 @@ from dask.distributed import LocalCluster, Client
|
|
|
13
13
|
# pyfemtet relative
|
|
14
14
|
from pyfemtet.opt.interface import FEMInterface, FemtetInterface
|
|
15
15
|
from pyfemtet.opt.opt import AbstractOptimizer, OptunaOptimizer
|
|
16
|
-
from pyfemtet.opt.visualization.
|
|
16
|
+
from pyfemtet.opt.visualization.process_monitor.application import main as process_monitor_main
|
|
17
17
|
from pyfemtet.opt._femopt_core import (
|
|
18
18
|
_check_bound,
|
|
19
19
|
_is_access_gogh,
|
|
@@ -574,6 +574,12 @@ def _start_monitor_server(
|
|
|
574
574
|
host=None,
|
|
575
575
|
port=None,
|
|
576
576
|
):
|
|
577
|
-
|
|
578
|
-
|
|
577
|
+
process_monitor_main(
|
|
578
|
+
history,
|
|
579
|
+
status,
|
|
580
|
+
worker_addresses,
|
|
581
|
+
worker_status_list,
|
|
582
|
+
host,
|
|
583
|
+
port,
|
|
584
|
+
)
|
|
579
585
|
return 'Exit monitor server process gracefully'
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Multi-objective optimization: heating element on substrate.
|
|
2
|
+
|
|
3
|
+
Using Femtet's heat conduction analysis solver, we will design
|
|
4
|
+
to reduce the chip temperature and shrink the board size.
|
|
5
|
+
|
|
6
|
+
Corresponding project: wat_ex14_parametric.femprj
|
|
7
|
+
"""
|
|
8
|
+
from pyfemtet.opt import FEMOpt
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def chip_temp(Femtet, chip_name):
|
|
12
|
+
"""Obtain the maximum temperature of the chip.
|
|
13
|
+
|
|
14
|
+
Note:
|
|
15
|
+
The objective or constraint function should take Femtet
|
|
16
|
+
as its first argument and return a float as the output.
|
|
17
|
+
|
|
18
|
+
Params:
|
|
19
|
+
Femtet: An instance for manipulating Femtet with macros. For detailed information, please refer to "Femtet Macro Help".
|
|
20
|
+
chip_name (str): The body attribute name defined in femprj. Valid values are 'MAINCHIP' or 'SUBCHIP'.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
float: The maximum temperature of the body with the specified body attribute name.
|
|
24
|
+
"""
|
|
25
|
+
Gogh = Femtet.Gogh
|
|
26
|
+
|
|
27
|
+
max_temperature, min_temperature, mean_temperature = Gogh.Watt.GetTemp(chip_name)
|
|
28
|
+
|
|
29
|
+
return max_temperature # unit: degree
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def substrate_size(Femtet):
|
|
33
|
+
"""Calculate the occupied area on the XY plane of the substrate."""
|
|
34
|
+
substrate_w = Femtet.GetVariableValue('substrate_w')
|
|
35
|
+
substrate_d = Femtet.GetVariableValue('substrate_d')
|
|
36
|
+
return substrate_w * substrate_d # unit: mm2
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == '__main__':
|
|
40
|
+
|
|
41
|
+
# Initialize the FEMOpt object.
|
|
42
|
+
# (establish connection between the optimization problem and Femtet)
|
|
43
|
+
femopt = FEMOpt()
|
|
44
|
+
|
|
45
|
+
# Add design variables to the optimization problem.
|
|
46
|
+
# (Specify the variables registered in the femprj file.)
|
|
47
|
+
femopt.add_parameter("substrate_w", 40, lower_bound=22, upper_bound=40)
|
|
48
|
+
femopt.add_parameter("substrate_d", 60, lower_bound=33, upper_bound=60)
|
|
49
|
+
|
|
50
|
+
# Add the objective function to the optimization problem.
|
|
51
|
+
# The target bending angle is 90 degrees.
|
|
52
|
+
femopt.add_objective(chip_temp, name='max temp. of<br>MAINCHIP (degree)', direction='minimize', args=('MAINCHIP',))
|
|
53
|
+
femopt.add_objective(chip_temp, name='max temp. of<br>SUBCHIP (degree)', direction='minimize', args=('SUBCHIP',))
|
|
54
|
+
femopt.add_objective(substrate_size, name='substrate size')
|
|
55
|
+
|
|
56
|
+
# Run optimization.
|
|
57
|
+
femopt.set_random_seed(42)
|
|
58
|
+
femopt.optimize(n_trials=15, n_parallel=3) # This line is the only difference with no parallel pattern.
|
|
59
|
+
|
|
60
|
+
# Stop script to keep process alive
|
|
61
|
+
# while you check the result in process monitor.
|
|
62
|
+
print('================================')
|
|
63
|
+
print('Finished. Press Enter to quit...')
|
|
64
|
+
print('================================')
|
|
65
|
+
input()
|
|
66
|
+
femopt.terminate_all()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""多目的最適化: プリント基板上ICの発熱
|
|
2
|
+
|
|
3
|
+
Femtetの熱伝導解析ソルバを使用して、ICチップの発熱を抑えつつ
|
|
4
|
+
基板サイズを小さくする設計を行います。
|
|
5
|
+
|
|
6
|
+
対応プロジェクト: wat_ex14_parametric_jp.femprj
|
|
7
|
+
"""
|
|
8
|
+
from pyfemtet.opt import FEMOpt
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def chip_temp(Femtet, chip_name):
|
|
12
|
+
"""チップの最高温度を取得します。
|
|
13
|
+
|
|
14
|
+
Note:
|
|
15
|
+
目的関数または制約関数は、
|
|
16
|
+
第一引数としてFemtetを受け取り、
|
|
17
|
+
戻り値としてfloat型を返す必要があります。
|
|
18
|
+
|
|
19
|
+
Params:
|
|
20
|
+
Femtet: Femtet をマクロで操作するためのインスタンスです。詳細な情報については、「Femtet マクロヘルプ」をご覧ください。
|
|
21
|
+
chip_name (str): femprj 内で定義されているボディ属性名です。有効な値は 'MAINCHIP' 又は 'SUBCHIP' です。
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
float: 指定されたボディ属性名のボディの最高温度です。
|
|
25
|
+
"""
|
|
26
|
+
Gogh = Femtet.Gogh
|
|
27
|
+
|
|
28
|
+
max_temperature, min_temperature, mean_temperature = Gogh.Watt.GetTemp(chip_name)
|
|
29
|
+
|
|
30
|
+
return max_temperature # 単位: 度
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def substrate_size(Femtet):
|
|
34
|
+
"""基板のXY平面上での専有面積を計算します。"""
|
|
35
|
+
substrate_w = Femtet.GetVariableValue('substrate_w')
|
|
36
|
+
substrate_d = Femtet.GetVariableValue('substrate_d')
|
|
37
|
+
return substrate_w * substrate_d # 単位: mm2
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == '__main__':
|
|
41
|
+
|
|
42
|
+
# FEMOpt オブジェクトの初期化 (最適化問題とFemtetとの接続を行います)
|
|
43
|
+
femopt = FEMOpt()
|
|
44
|
+
|
|
45
|
+
# 設計変数を最適化問題に追加 (femprj ファイルに登録されている変数を指定してください)
|
|
46
|
+
femopt.add_parameter("substrate_w", 40, lower_bound=22, upper_bound=60)
|
|
47
|
+
femopt.add_parameter("substrate_d", 60, lower_bound=34, upper_bound=60)
|
|
48
|
+
|
|
49
|
+
# 目的関数を最適化問題に追加
|
|
50
|
+
femopt.add_objective(chip_temp, name='MAINCHIP<br>最高温度(度)', direction='minimize', args=('MAINCHIP',))
|
|
51
|
+
femopt.add_objective(chip_temp, name='SUBCHIP<br>最高温度(度)', direction='minimize', args=('SUBCHIP',))
|
|
52
|
+
femopt.add_objective(substrate_size, name='基板サイズ(mm2)')
|
|
53
|
+
|
|
54
|
+
# 最適化を実行
|
|
55
|
+
femopt.set_random_seed(42)
|
|
56
|
+
femopt.optimize(n_trials=15, n_parallel=3) # この部分のみ変更します
|
|
57
|
+
|
|
58
|
+
# プロセスモニタで結果を確認するために
|
|
59
|
+
# Enter キーが押されるまで処理を停止します。
|
|
60
|
+
print('================================')
|
|
61
|
+
print('Finished. Press Enter to quit...')
|
|
62
|
+
print('================================')
|
|
63
|
+
input()
|
|
64
|
+
femopt.terminate_all()
|
|
@@ -3,15 +3,19 @@ from typing import Optional, List
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
5
|
from time import sleep, time
|
|
6
|
-
import signal
|
|
7
6
|
|
|
8
7
|
import pandas as pd
|
|
9
8
|
import psutil
|
|
10
9
|
from dask.distributed import get_worker
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
# noinspection PyUnresolvedReferences
|
|
12
|
+
from pywintypes import com_error, error
|
|
13
|
+
# noinspection PyUnresolvedReferences
|
|
13
14
|
from pythoncom import CoInitialize, CoUninitialize
|
|
15
|
+
# noinspection PyUnresolvedReferences
|
|
14
16
|
from win32com.client import constants
|
|
17
|
+
import win32con
|
|
18
|
+
import win32gui
|
|
15
19
|
from femtetutils import util
|
|
16
20
|
|
|
17
21
|
from pyfemtet.core import (
|
|
@@ -31,6 +35,10 @@ from pyfemtet.dispatch_extensions import (
|
|
|
31
35
|
from pyfemtet.opt.interface import FEMInterface, logger
|
|
32
36
|
|
|
33
37
|
|
|
38
|
+
def post_activate_message(hwnd):
|
|
39
|
+
win32gui.PostMessage(hwnd, win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)
|
|
40
|
+
|
|
41
|
+
|
|
34
42
|
class FemtetInterface(FEMInterface):
|
|
35
43
|
"""Concrete class for the interface with Femtet.
|
|
36
44
|
|
|
@@ -113,7 +121,7 @@ class FemtetInterface(FEMInterface):
|
|
|
113
121
|
if self.original_femprj_path is None:
|
|
114
122
|
# dask worker でなければ original のはず
|
|
115
123
|
try:
|
|
116
|
-
|
|
124
|
+
_ = get_worker()
|
|
117
125
|
except ValueError:
|
|
118
126
|
self.original_femprj_path = self.femprj_path
|
|
119
127
|
|
|
@@ -252,7 +260,7 @@ class FemtetInterface(FEMInterface):
|
|
|
252
260
|
|
|
253
261
|
"""
|
|
254
262
|
|
|
255
|
-
# FIXME: Gaudi へのアクセスなど、self.Femtet.Gaudi.
|
|
263
|
+
# FIXME: Gaudi へのアクセスなど、self.Femtet.Gaudi.SomeFunc() のような場合、この関数を呼び出す前に Gaudi へのアクセスの時点で com_error が起こる
|
|
256
264
|
# FIXME: => 文字列で渡して eval() すればよい。
|
|
257
265
|
|
|
258
266
|
if args is None:
|
|
@@ -282,9 +290,16 @@ class FemtetInterface(FEMInterface):
|
|
|
282
290
|
|
|
283
291
|
# API を実行
|
|
284
292
|
try:
|
|
285
|
-
|
|
286
|
-
|
|
293
|
+
# 解析結果を開いた状態で Gaudi.Activate して ReExecute する場合、ReExecute の前後にアクティブ化イベントが必要
|
|
294
|
+
if fun.__name__ == 'ReExecute':
|
|
295
|
+
post_activate_message(self.Femtet.hWnd) # can raise pywintypes.error
|
|
296
|
+
returns = fun(*args, **kwargs)
|
|
297
|
+
post_activate_message(self.Femtet.hWnd)
|
|
298
|
+
else:
|
|
299
|
+
returns = fun(*args, **kwargs)
|
|
300
|
+
except (com_error, error):
|
|
287
301
|
# パターン 2 エラーが生じたことは確定なのでエラーが起こるよう returns を作る
|
|
302
|
+
# com_error ではなく error の場合はおそらく Femtet が落ちている
|
|
288
303
|
if ret_for_check_idx is None:
|
|
289
304
|
returns = return_value_if_failed
|
|
290
305
|
else:
|
|
@@ -665,6 +680,13 @@ class FemtetInterface(FEMInterface):
|
|
|
665
680
|
)
|
|
666
681
|
return out
|
|
667
682
|
|
|
683
|
+
@staticmethod
|
|
684
|
+
def create_pdt_path(femprj_path, model_name, trial):
|
|
685
|
+
result_dir = femprj_path.replace('.femprj', '.Results')
|
|
686
|
+
pdt_path = os.path.join(result_dir, model_name + f'_trial{trial}.pdt')
|
|
687
|
+
return pdt_path
|
|
688
|
+
|
|
689
|
+
# noinspection PyMethodOverriding
|
|
668
690
|
@staticmethod
|
|
669
691
|
def postprocess_func(
|
|
670
692
|
trial: int,
|
|
@@ -676,7 +698,7 @@ class FemtetInterface(FEMInterface):
|
|
|
676
698
|
):
|
|
677
699
|
result_dir = original_femprj_path.replace('.femprj', '.Results')
|
|
678
700
|
if pdt_file_content is not None:
|
|
679
|
-
pdt_path =
|
|
701
|
+
pdt_path = FemtetInterface.create_pdt_path(original_femprj_path, model_name, trial)
|
|
680
702
|
with open(pdt_path, 'wb') as f:
|
|
681
703
|
f.write(pdt_file_content)
|
|
682
704
|
|
|
@@ -710,13 +732,12 @@ class FemtetInterface(FEMInterface):
|
|
|
710
732
|
jpg_path = os.path.join(result_dir, self.model_name + '.jpg')
|
|
711
733
|
|
|
712
734
|
# モデル表示画面の設定
|
|
713
|
-
self.Femtet.SetWindowSize(
|
|
735
|
+
self.Femtet.SetWindowSize(600, 600)
|
|
714
736
|
self.Femtet.Fit()
|
|
715
|
-
self.Femtet.ViewNumeric.SetCoord(1, 1, 1)
|
|
716
737
|
|
|
717
738
|
# ---モデルの画面を保存---
|
|
718
739
|
self.Femtet.Redraw() # 再描画
|
|
719
|
-
succeed = self.Femtet.SavePicture(jpg_path,
|
|
740
|
+
succeed = self.Femtet.SavePicture(jpg_path, 600, 600, 80)
|
|
720
741
|
|
|
721
742
|
self.Femtet.RedrawMode = True # 逐一の描画をオン
|
|
722
743
|
|
|
@@ -745,6 +766,7 @@ class _UnPicklableNoFEM(FemtetInterface):
|
|
|
745
766
|
Femtet = None
|
|
746
767
|
quit_when_destruct = False
|
|
747
768
|
|
|
769
|
+
# noinspection PyMissingConstructor
|
|
748
770
|
def __init__(self):
|
|
749
771
|
CoInitialize()
|
|
750
772
|
self.unpicklable_member = Dispatch('FemtetMacro.Femtet')
|
|
@@ -1,36 +1,15 @@
|
|
|
1
|
+
from femtetutils import util
|
|
1
2
|
from pyfemtet.dispatch_extensions import _get_pid
|
|
2
3
|
|
|
3
|
-
import winreg
|
|
4
4
|
import ctypes
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def _get_dll(
|
|
8
|
-
|
|
9
|
-
dll_path =
|
|
7
|
+
def _get_dll():
|
|
8
|
+
femtet_exe_path = util.get_femtet_exe_path()
|
|
9
|
+
dll_path = femtet_exe_path.replace('Femtet.exe', 'ParametricIF.dll')
|
|
10
10
|
return ctypes.cdll.LoadLibrary(dll_path)
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def _get_femtet_major_version(Femtet):
|
|
14
|
-
from pyfemtet.core import _version
|
|
15
|
-
version_int8 = _version(Femtet=Femtet)
|
|
16
|
-
return str(version_int8)[0:4]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def _get_parametric_dll_path(femtet_major_version) -> str:
|
|
20
|
-
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\FemtetInfo\InstallVersion\x64')
|
|
21
|
-
_, nValues, _ = winreg.QueryInfoKey(key)
|
|
22
|
-
for i in range(nValues):
|
|
23
|
-
name, data, _ = winreg.EnumValue(key, i)
|
|
24
|
-
if name == str(femtet_major_version):
|
|
25
|
-
winreg.CloseKey(key)
|
|
26
|
-
import os
|
|
27
|
-
dll_path = os.path.join(data, 'Program', 'ParametricIF.dll')
|
|
28
|
-
return dll_path
|
|
29
|
-
# ここまで来ていたら失敗
|
|
30
|
-
winreg.CloseKey(key)
|
|
31
|
-
raise RuntimeError('パラメトリック解析機能へのアクセスに失敗しました')
|
|
32
|
-
|
|
33
|
-
|
|
34
13
|
def _get_dll_with_set_femtet(Femtet):
|
|
35
14
|
dll = _get_dll(Femtet)
|
|
36
15
|
pid = _get_pid(Femtet.hWnd)
|
|
@@ -40,6 +19,7 @@ def _get_dll_with_set_femtet(Femtet):
|
|
|
40
19
|
|
|
41
20
|
|
|
42
21
|
def _get_prm_result_names(Femtet):
|
|
22
|
+
"""Used by pyfemtet-opt-gui"""
|
|
43
23
|
out = []
|
|
44
24
|
|
|
45
25
|
# load dll and set target femtet
|
pyfemtet/opt/opt/_base.py
CHANGED
|
@@ -65,10 +65,15 @@ class AbstractOptimizer(ABC):
|
|
|
65
65
|
|
|
66
66
|
# x の更新
|
|
67
67
|
self.parameters['value'] = x
|
|
68
|
+
logger.info(f'Start calculation with input: {x}')
|
|
68
69
|
|
|
69
70
|
# FEM の更新
|
|
70
71
|
logger.debug('fem.update() start')
|
|
71
|
-
|
|
72
|
+
try:
|
|
73
|
+
self.fem.update(self.parameters)
|
|
74
|
+
except Exception as e:
|
|
75
|
+
logger.warning('An exception has occurred during FEM update.')
|
|
76
|
+
raise e
|
|
72
77
|
|
|
73
78
|
# y, _y, c の更新
|
|
74
79
|
logger.debug('calculate y start')
|
|
@@ -93,6 +98,9 @@ class AbstractOptimizer(ABC):
|
|
|
93
98
|
)
|
|
94
99
|
|
|
95
100
|
logger.debug('history.record end')
|
|
101
|
+
|
|
102
|
+
logger.info(f'End calculation with output: {_y}')
|
|
103
|
+
|
|
96
104
|
return np.array(y), np.array(_y), np.array(c)
|
|
97
105
|
|
|
98
106
|
def _reconstruct_fem(self, skip_reconstruct=False):
|
pyfemtet/opt/opt/_optuna.py
CHANGED
|
@@ -18,6 +18,10 @@ from pyfemtet.core import MeshError, ModelError, SolveError
|
|
|
18
18
|
# filter warnings
|
|
19
19
|
import warnings
|
|
20
20
|
from optuna.exceptions import ExperimentalWarning
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
optuna.logging.set_verbosity(optuna.logging.ERROR)
|
|
24
|
+
|
|
21
25
|
warnings.filterwarnings('ignore', category=ExperimentalWarning)
|
|
22
26
|
|
|
23
27
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Create autocompletable components"""
|
|
2
|
+
import os
|
|
3
|
+
import inspect
|
|
4
|
+
|
|
5
|
+
from dash.development.base_component import Component
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# noinspection PyUnresolvedReferences
|
|
9
|
+
from dash import html, dcc, dash_table
|
|
10
|
+
# noinspection PyUnresolvedReferences
|
|
11
|
+
import dash_bootstrap_components as dbc
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
here, me = os.path.split(__file__)
|
|
15
|
+
COMPONENT_FILE_DIR = os.path.join(here, 'wrapped_components')
|
|
16
|
+
indent = ' '
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def create(module_name: str) -> str:
|
|
20
|
+
header = '''# auto created module
|
|
21
|
+
from pyfemtet.opt.visualization.wrapped_components.str_enum import StrEnum
|
|
22
|
+
# from enum import StrEnum
|
|
23
|
+
import dash
|
|
24
|
+
import dash_bootstrap_components
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
'''
|
|
28
|
+
path = os.path.join(COMPONENT_FILE_DIR, module_name.replace('.py', '') + '.py')
|
|
29
|
+
with open(path, 'w', newline='\n') as f:
|
|
30
|
+
f.write(header)
|
|
31
|
+
return path
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def append(html_class, module_path: str):
|
|
35
|
+
print('==========')
|
|
36
|
+
print(html_class)
|
|
37
|
+
|
|
38
|
+
# get property names
|
|
39
|
+
init_signature = inspect.signature(html_class.__init__)
|
|
40
|
+
props = [param.name for param in init_signature.parameters.values() if (param.name != 'self') and (param.name != 'args') and (param.name != 'kwargs')]
|
|
41
|
+
|
|
42
|
+
# create class definition
|
|
43
|
+
class_definition = f'class {html_class.__name__}({html_class.__module__}):\n' # library specific
|
|
44
|
+
|
|
45
|
+
# create id property
|
|
46
|
+
class_definition += indent + 'def _dummy(self):\n'
|
|
47
|
+
class_definition += indent*2 + '# noinspection PyAttributeOutsideInit\n'
|
|
48
|
+
class_definition += indent*2 + 'self.id = None\n\n'
|
|
49
|
+
|
|
50
|
+
# create Prop attribute
|
|
51
|
+
class_definition += indent + 'class Prop(StrEnum):\n'
|
|
52
|
+
for available_property in props:
|
|
53
|
+
property_definition = f'{available_property} = "{available_property}"'
|
|
54
|
+
try:
|
|
55
|
+
exec(property_definition)
|
|
56
|
+
except (SyntaxError, TypeError):
|
|
57
|
+
continue
|
|
58
|
+
class_definition += indent*2 + f'{property_definition}\n'
|
|
59
|
+
|
|
60
|
+
if class_definition.endswith(':\n'):
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
class_definition += '\n\n'
|
|
64
|
+
|
|
65
|
+
with open(module_path, 'a', newline='\n') as f:
|
|
66
|
+
f.write(class_definition)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def sub(module_name):
|
|
70
|
+
# glob component classes
|
|
71
|
+
module_path = create(module_name)
|
|
72
|
+
class_names = dir(eval(module_name))
|
|
73
|
+
for class_name in class_names:
|
|
74
|
+
cls = eval(f'{module_name}.{class_name}')
|
|
75
|
+
if not inspect.isclass(cls):
|
|
76
|
+
continue
|
|
77
|
+
if issubclass(cls, Component):
|
|
78
|
+
append(cls, module_path)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def main():
|
|
82
|
+
# html
|
|
83
|
+
sub('html')
|
|
84
|
+
|
|
85
|
+
# dcc
|
|
86
|
+
sub('dcc')
|
|
87
|
+
|
|
88
|
+
# dbc
|
|
89
|
+
sub('dbc')
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == '__main__':
|
|
93
|
+
main()
|