pyfemtet 0.4.1__py3-none-any.whl → 0.4.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyfemtet might be problematic. Click here for more details.

Files changed (51) hide show
  1. pyfemtet/FemtetPJTSample/NX_ex01/NX_ex01.py +60 -31
  2. pyfemtet/FemtetPJTSample/Sldworks_ex01/Sldworks_ex01.py +61 -39
  3. pyfemtet/FemtetPJTSample/_her_ex40_parametric.py +148 -0
  4. pyfemtet/FemtetPJTSample/gau_ex08_parametric.py +25 -22
  5. pyfemtet/FemtetPJTSample/her_ex40_parametric.py +59 -47
  6. pyfemtet/FemtetPJTSample/wat_ex14_parallel_parametric.py +31 -29
  7. pyfemtet/FemtetPJTSample/wat_ex14_parametric.py +29 -27
  8. pyfemtet/__init__.py +1 -1
  9. pyfemtet/opt/_femopt_core.py +3 -1
  10. pyfemtet/opt/femprj_sample/cad_ex01_NX.femprj +0 -0
  11. pyfemtet/opt/femprj_sample/cad_ex01_NX.prt +0 -0
  12. pyfemtet/opt/femprj_sample/cad_ex01_NX.py +132 -0
  13. pyfemtet/opt/femprj_sample/cad_ex01_SW.SLDPRT +0 -0
  14. pyfemtet/opt/femprj_sample/cad_ex01_SW.femprj +0 -0
  15. pyfemtet/opt/femprj_sample/cad_ex01_SW.py +132 -0
  16. pyfemtet/opt/femprj_sample/gal_ex58_parametric.femprj +0 -0
  17. pyfemtet/opt/femprj_sample/gal_ex58_parametric.py +75 -0
  18. pyfemtet/opt/femprj_sample/gau_ex08_parametric.femprj +0 -0
  19. pyfemtet/opt/femprj_sample/gau_ex08_parametric.py +59 -0
  20. pyfemtet/opt/femprj_sample/her_ex40_parametric.femprj +0 -0
  21. pyfemtet/opt/femprj_sample/her_ex40_parametric.py +137 -0
  22. pyfemtet/opt/femprj_sample/paswat_ex1_parametric.femprj +0 -0
  23. pyfemtet/opt/femprj_sample/paswat_ex1_parametric.py +61 -0
  24. pyfemtet/opt/femprj_sample/paswat_ex1_parametric_parallel.py +62 -0
  25. pyfemtet/opt/femprj_sample/wat_ex14_parametric.femprj +0 -0
  26. pyfemtet/opt/femprj_sample/wat_ex14_parametric.py +59 -0
  27. pyfemtet/opt/femprj_sample_jp/cad_ex01_NX_jp.femprj +0 -0
  28. pyfemtet/opt/femprj_sample_jp/cad_ex01_NX_jp.py +126 -0
  29. pyfemtet/opt/femprj_sample_jp/cad_ex01_SW_jp.femprj +0 -0
  30. pyfemtet/opt/femprj_sample_jp/cad_ex01_SW_jp.py +126 -0
  31. pyfemtet/opt/femprj_sample_jp/gal_ex58_parametric_jp.femprj +0 -0
  32. pyfemtet/opt/femprj_sample_jp/gal_ex58_parametric_jp.py +71 -0
  33. pyfemtet/opt/femprj_sample_jp/gau_ex08_parametric_jp.femprj +0 -0
  34. pyfemtet/opt/femprj_sample_jp/gau_ex08_parametric_jp.py +58 -0
  35. pyfemtet/opt/femprj_sample_jp/her_ex40_parametric_jp.femprj +0 -0
  36. pyfemtet/opt/femprj_sample_jp/her_ex40_parametric_jp.py +137 -0
  37. pyfemtet/opt/femprj_sample_jp/paswat_ex1_parametric_jp.femprj +0 -0
  38. pyfemtet/opt/femprj_sample_jp/paswat_ex1_parametric_jp.py +59 -0
  39. pyfemtet/opt/femprj_sample_jp/paswat_ex1_parametric_parallel_jp.py +60 -0
  40. pyfemtet/opt/femprj_sample_jp/wat_ex14_parametric_jp.femprj +0 -0
  41. pyfemtet/opt/femprj_sample_jp/wat_ex14_parametric_jp.py +57 -0
  42. pyfemtet/opt/interface/_femtet.py +6 -2
  43. pyfemtet/opt/interface/_femtet_with_nx/_interface.py +2 -8
  44. pyfemtet/opt/interface/_femtet_with_sldworks.py +2 -8
  45. pyfemtet/opt/opt/_optuna.py +6 -0
  46. {pyfemtet-0.4.1.dist-info → pyfemtet-0.4.3.dist-info}/METADATA +3 -2
  47. pyfemtet-0.4.3.dist-info/RECORD +71 -0
  48. pyfemtet-0.4.1.dist-info/RECORD +0 -38
  49. {pyfemtet-0.4.1.dist-info → pyfemtet-0.4.3.dist-info}/LICENSE +0 -0
  50. {pyfemtet-0.4.1.dist-info → pyfemtet-0.4.3.dist-info}/WHEEL +0 -0
  51. {pyfemtet-0.4.1.dist-info → pyfemtet-0.4.3.dist-info}/entry_points.txt +0 -0
@@ -1,3 +1,9 @@
1
+ """Single-objective optimization: Resonant frequency of a circular patch antenna
2
+
3
+ Using Femtet’s electromagnetic wave analysis solver,
4
+ we explain an example of setting the resonant frequency
5
+ of a circular patch antenna to a specific value.
6
+ """
1
7
  from time import sleep
2
8
 
3
9
  import numpy as np
@@ -8,9 +14,8 @@ from optuna.integration.botorch import BoTorchSampler
8
14
  from pyfemtet.opt import OptunaOptimizer, FEMOpt
9
15
 
10
16
 
11
-
12
17
  class SParameterCalculator:
13
- """S パラメータ・共振周波数計算用クラスです。"""
18
+ """This class is for calculating S-parameters and resonance frequencies."""
14
19
 
15
20
  def __init__(self):
16
21
  self.freq = []
@@ -20,51 +25,55 @@ class SParameterCalculator:
20
25
  self.minimum_S = None
21
26
 
22
27
  def get_result_from_Femtet(self, Femtet):
23
- """Femtet の解析結果から周波数と S パラメータの関係を取得します。"""
28
+ """Obtain the relationship between frequency and S-parameter from the Femtet analysis results."""
24
29
 
25
- # 前準備
30
+ # Preparation
26
31
  Femtet.OpenCurrentResult(True)
27
32
  Gogh = Femtet.Gogh
28
33
 
29
- # 各モードに対して周波数と S(1,1) を取得する
34
+ # Obtain the frequency and S(1,1) for each mode
30
35
  mode = 0
31
36
  freq_list = []
32
37
  dB_S_list = []
33
- for mode in tqdm(range(Gogh.Hertz.nMode), '結果取得中'):
34
- # Femtet 結果画面のモード設定
38
+ for mode in tqdm(range(Gogh.Hertz.nMode), 'Obtaining frequency and S-parameter'):
39
+ # Femtet result screen mode settings
35
40
  Gogh.Hertz.Mode = mode
36
41
  sleep(0.01)
37
- # 周波数の取得
42
+ # Get frequency
38
43
  freq = Gogh.Hertz.GetFreq().Real
39
- # S パラメータの取得
44
+ # Get S-parameters
40
45
  comp_S = Gogh.Hertz.GetSMatrix(0, 0)
41
46
  norm = np.linalg.norm((comp_S.Real, comp_S.Imag))
42
47
  dB_S = 20 * np.log10(norm)
43
- # 結果の取得
48
+ # Get results
44
49
  freq_list.append(freq)
45
50
  dB_S_list.append(dB_S)
46
51
  self.freq = freq_list
47
52
  self.S = dB_S_list
48
53
 
49
54
  def calc_resonance_frequency(self):
50
- """S に対して最初のピークを与える freq を計算します。"""
55
+ """Compute the frequency that gives the first peak for S-parameter."""
51
56
  x = -np.array(self.S)
52
57
  peaks, _ = find_peaks(x, height=None, threshold=None, distance=None, prominence=0.5, width=None, wlen=None, rel_height=0.5, plateau_size=None)
53
58
  from pyfemtet.core import SolveError
54
59
  if len(peaks) == 0:
55
- raise SolveError('ピークが検出されませんでした。')
60
+ raise SolveError('No peaks detected.')
56
61
  self.resonance_frequency = self.freq[peaks[0]]
57
62
  self.minimum_S = self.S[peaks[0]]
58
63
 
59
64
  def get_resonance_frequency(self, Femtet):
60
- """共振周波数を計算します。
61
-
62
- Femtet : マクロを使用するためのインスタンスです。詳しくは "Femtet マクロヘルプ / CFemtet クラス" をご覧ください。
63
- 目的関数は第一引数に Femtet インスタンスを取る必要があります。
65
+ """Calculate the resonant frequency.
64
66
 
65
- f : 計算された共振周波数です。
66
- 目的関数は単一の float を返す必要があります。
67
+ Note:
68
+ The objective or constraint function
69
+ must take a Femtet as its first argument
70
+ and must return a single float.
67
71
 
72
+ Params:
73
+ Femtet: An instance for using Femtet macros. For more information, see "Femtet Macro Help / CFemtet Class".
74
+
75
+ Returns:
76
+ float: A resonance frequency.
68
77
  """
69
78
  self.get_result_from_Femtet(Femtet)
70
79
  self.calc_resonance_frequency()
@@ -73,14 +82,16 @@ class SParameterCalculator:
73
82
 
74
83
 
75
84
  def antenna_is_smaller_than_substrate(Femtet):
76
- """アンテナのサイズと基板のサイズの関係を計算します。
77
-
78
- Femtet : マクロを使用するためのインスタンスです。詳しくは "Femtet マクロヘルプ / CFemtet クラス" をご覧ください。
79
- 拘束関数は第一引数に Femtet インスタンスを取る必要があります。
85
+ """Calculate the relationship between antenna size and board size.
80
86
 
81
- Sx/2 - ant_r : 基板サイズとアンテナサイズの差です。
82
- 拘束関数は単一の float を返す必要があります。
87
+ This function is used to constrain the model
88
+ from breaking down while changing parameters.
83
89
 
90
+ Params:
91
+ Femtet: An instance for using Femtet macros.
92
+
93
+ Returns:
94
+ float: Difference between the board size and antenna size. Must be equal to or grater than 1 mm.
84
95
  """
85
96
  ant_r = Femtet.GetVariableValue('ant_r')
86
97
  Sx = Femtet.GetVariableValue('sx')
@@ -88,14 +99,16 @@ def antenna_is_smaller_than_substrate(Femtet):
88
99
 
89
100
 
90
101
  def port_is_inside_antenna(Femtet):
91
- """給電ポートの位置とアンテナのサイズの関係を計算します。
92
-
93
- Femtet : マクロを使用するためのインスタンスです。詳しくは "Femtet マクロヘルプ / CFemtet クラス" をご覧ください。
94
- 拘束関数は第一引数に Femtet インスタンスを取る必要があります。
102
+ """Calculate the relationship between the feed port location and antenna size.
95
103
 
96
- ant_r - xf : アンテナ辺縁と給電ポートの位置の差です。
97
- 拘束関数は単一の float を返す必要があります。
104
+ This function is used to constrain the model
105
+ from breaking down while changing parameters.
98
106
 
107
+ Params:
108
+ Femtet: An instance for using Femtet macros.
109
+
110
+ Returns:
111
+ float: Difference between the antenna edge and the position of the feed port. Must be equal to or grater than 1 mm.
99
112
  """
100
113
  ant_r = Femtet.GetVariableValue('ant_r')
101
114
  xf = Femtet.GetVariableValue('xf')
@@ -103,10 +116,10 @@ def port_is_inside_antenna(Femtet):
103
116
 
104
117
 
105
118
  if __name__ == '__main__':
106
- # S パラメータ計算用クラス
119
+ # Define the object for calculating S-parameters and resonance frequencies.
107
120
  s = SParameterCalculator()
108
121
 
109
- # 最適化手法を定義するオブジェクトを用意
122
+ # Define mathematical optimization object.
110
123
  opt = OptunaOptimizer(
111
124
  sampler_class=BoTorchSampler,
112
125
  sampler_kwargs=dict(
@@ -114,22 +127,21 @@ if __name__ == '__main__':
114
127
  )
115
128
  )
116
129
 
117
- # 最適化処理を行うオブジェクトを用意
118
- femopt = FEMOpt(
119
- opt=opt,
120
- ) # ここで起動している Femtet が紐づけされます
130
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
131
+ femopt = FEMOpt(opt=opt)
121
132
 
122
- # 設計変数の設定
123
- femopt.add_parameter('ant_r', 10, 5, 20, memo='円形アンテナの半径')
124
- femopt.add_parameter('sx', 50, 40, 60, memo='基板のサイズ')
125
- femopt.add_parameter('xf', 5, 1, 20, memo='給電ポートの偏心量')
126
-
127
- # 拘束の設定
128
- femopt.add_constraint(antenna_is_smaller_than_substrate, 'アンテナサイズ', lower_bound=1)
129
- femopt.add_constraint(port_is_inside_antenna, 'ポート位置', lower_bound=1)
130
-
131
- # 目的の設定
132
- femopt.add_objective(s.get_resonance_frequency, '第一共振周波数(GHz)', direction=3.0)
133
+ # Add design variables (Use variable names set in Femtet) to the optimization problem.
134
+ femopt.add_parameter('ant_r', 10, 5, 20)
135
+ femopt.add_parameter('sx', 50, 40, 60)
136
+ femopt.add_parameter('xf', 5, 1, 20)
137
+
138
+ # Add constraint to the optimization problem.
139
+ femopt.add_constraint(antenna_is_smaller_than_substrate, 'board_antenna_clearance', lower_bound=1)
140
+ femopt.add_constraint(port_is_inside_antenna, 'antenna_port_clearance', lower_bound=1)
141
+
142
+ # Add objective to the optimization problem.
143
+ # The target frequency is 3 GHz.
144
+ femopt.add_objective(s.get_resonance_frequency, 'First_resonant_frequency(GHz)', direction=3.0)
133
145
 
134
146
  femopt.set_random_seed(42)
135
147
  femopt.optimize(n_trials=20)
@@ -1,23 +1,26 @@
1
- """基板上の発熱体
1
+ """Parallel computing / Multi-objective optimization: heating element on board
2
2
 
3
- wat_ex14_parametric.femprj に対し熱伝導解析を行い、
4
- チップの発熱による温度上昇を最小にしつつ
5
- 基板寸法を最小にする
6
- 基板寸法・チップ配置寸法を探索します。
3
+ Perform thermal conduction analysis on wat_ex14_parametric.femprj
4
+ and search for board dimensions and chip placement dimensions that
5
+ minimize the board dimensions while minimizing the temperature rise
6
+ due to chip heat generation.
7
7
  """
8
-
9
8
  from pyfemtet.opt import FEMOpt
10
9
 
11
10
 
12
11
  def max_temperature(Femtet, body_name):
13
- """Femtet の解析結果からチップの最高温度を取得します。
12
+ """Get the maximum temperature of the chip.
14
13
 
15
- Femtet : マクロを使用するためのインスタンスです。詳しくは "Femtet マクロヘルプ / CFemtet クラス" をご覧ください。
16
- 目的関数は第一引数に Femtet インスタンスを取る必要があります。
14
+ Note:
15
+ The objective or constraint function
16
+ must take a Femtet as its first argument
17
+ and must return a single float.
17
18
 
18
- max_temp : 計算された最高温度です。
19
- 目的関数は単一の float を返す必要があります。
19
+ Params:
20
+ Femtet: An instance for using Femtet macros. For more information, see "Femtet Macro Help / CFemtet Class".
20
21
 
22
+ Returns:
23
+ float: Max-temperature.
21
24
  """
22
25
  Gogh = Femtet.Gogh
23
26
 
@@ -27,14 +30,13 @@ def max_temperature(Femtet, body_name):
27
30
 
28
31
 
29
32
  def substrate_size(Femtet):
30
- """Femtet の設計変数から基板サイズを取得します。
31
-
32
- Femtet : マクロを使用するためのインスタンスです。詳しくは "Femtet マクロヘルプ / CFemtet クラス" をご覧ください。
33
- 目的関数は第一引数に Femtet インスタンスを取る必要があります。
34
-
35
- subs_w * subs_d : XY 平面における基板の占有面積です。
36
- 目的関数は単一の float を返す必要があります。
33
+ """Calculate the substrate size.
37
34
 
35
+ Params:
36
+ Femtet: An instance for using Femtet macros. For more information, see "Femtet Macro Help / CFemtet Class".
37
+
38
+ Returns:
39
+ float: The area occupied by the board in the XY plane.
38
40
  """
39
41
  subs_w = Femtet.GetVariableValue('substrate_w')
40
42
  subs_d = Femtet.GetVariableValue('substrate_d')
@@ -44,20 +46,20 @@ def substrate_size(Femtet):
44
46
 
45
47
  if __name__ == '__main__':
46
48
 
47
- # 最適化処理を行うオブジェクトを用意
49
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
48
50
  femopt = FEMOpt()
49
51
 
50
- # 設計変数の設定
51
- femopt.add_parameter("substrate_w", 40, lower_bound=22, upper_bound=40, memo='基板サイズ X')
52
- femopt.add_parameter("substrate_d", 60, lower_bound=33, upper_bound=60, memo='基板サイズ Y')
52
+ # Add design variables (Use variable names set in Femtet) to the optimization problem.
53
+ femopt.add_parameter("substrate_w", 40, lower_bound=22, upper_bound=40)
54
+ femopt.add_parameter("substrate_d", 60, lower_bound=33, upper_bound=60)
53
55
 
54
- # 目的関数の設定
55
- femopt.add_objective(max_temperature, name='メインチップ温度', args=('MAINCHIP',))
56
- femopt.add_objective(max_temperature, name='サブチップ温度', args=('SUBCHIP',))
57
- femopt.add_objective(substrate_size, name='基板サイズ')
56
+ # Add objective to the optimization problem.
57
+ femopt.add_objective(max_temperature, name='main chip temp.', args=('MAINCHIP',))
58
+ femopt.add_objective(max_temperature, name='sub chip temp.', args=('SUBCHIP',))
59
+ femopt.add_objective(substrate_size, name='substrate size')
58
60
 
59
- # 最適化の実行
61
+ # Run optimization.
60
62
  femopt.set_random_seed(42)
61
- # femopt.main(n_trials=20)
62
- femopt.optimize(n_trials=20, n_parallel=3) # ここのみ wat_ex14_parametric.py から変更しました。
63
+ # femopt.optimize(n_trials=20)
64
+ femopt.optimize(n_trials=20, n_parallel=3) # Change only this line.
63
65
  femopt.terminate_all()
@@ -1,23 +1,26 @@
1
- """基板上の発熱体
1
+ """Multi-objective optimization: heating element on board
2
2
 
3
- wat_ex14_parametric.femprj に対し熱伝導解析を行い、
4
- チップの発熱による温度上昇を最小にしつつ
5
- 基板寸法を最小にする
6
- 基板寸法・チップ配置寸法を探索します。
3
+ Perform thermal conduction analysis on wat_ex14_parametric.femprj
4
+ and search for board dimensions and chip placement dimensions that
5
+ minimize the board dimensions while minimizing the temperature rise
6
+ due to chip heat generation.
7
7
  """
8
-
9
8
  from pyfemtet.opt import FEMOpt
10
9
 
11
10
 
12
11
  def max_temperature(Femtet, body_name):
13
- """Femtet の解析結果からチップの最高温度を取得します。
12
+ """Get the maximum temperature of the chip.
14
13
 
15
- Femtet : マクロを使用するためのインスタンスです。詳しくは "Femtet マクロヘルプ / CFemtet クラス" をご覧ください。
16
- 目的関数は第一引数に Femtet インスタンスを取る必要があります。
14
+ Note:
15
+ The objective or constraint function
16
+ must take a Femtet as its first argument
17
+ and must return a single float.
17
18
 
18
- max_temp : 計算された最高温度です。
19
- 目的関数は単一の float を返す必要があります。
19
+ Params:
20
+ Femtet: An instance for using Femtet macros. For more information, see "Femtet Macro Help / CFemtet Class".
20
21
 
22
+ Returns:
23
+ float: Max-temperature.
21
24
  """
22
25
  Gogh = Femtet.Gogh
23
26
 
@@ -27,14 +30,13 @@ def max_temperature(Femtet, body_name):
27
30
 
28
31
 
29
32
  def substrate_size(Femtet):
30
- """Femtet の設計変数から基板サイズを取得します。
31
-
32
- Femtet : マクロを使用するためのインスタンスです。詳しくは "Femtet マクロヘルプ / CFemtet クラス" をご覧ください。
33
- 目的関数は第一引数に Femtet インスタンスを取る必要があります。
34
-
35
- subs_w * subs_d : XY 平面における基板の占有面積です。
36
- 目的関数は単一の float を返す必要があります。
33
+ """Calculate the substrate size.
37
34
 
35
+ Params:
36
+ Femtet: An instance for using Femtet macros. For more information, see "Femtet Macro Help / CFemtet Class".
37
+
38
+ Returns:
39
+ float: The area occupied by the board in the XY plane.
38
40
  """
39
41
  subs_w = Femtet.GetVariableValue('substrate_w')
40
42
  subs_d = Femtet.GetVariableValue('substrate_d')
@@ -44,19 +46,19 @@ def substrate_size(Femtet):
44
46
 
45
47
  if __name__ == '__main__':
46
48
 
47
- # 最適化処理を行うオブジェクトを用意
49
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
48
50
  femopt = FEMOpt()
49
51
 
50
- # 設計変数の設定
51
- femopt.add_parameter("substrate_w", 40, lower_bound=22, upper_bound=40, memo='基板サイズ X')
52
- femopt.add_parameter("substrate_d", 60, lower_bound=33, upper_bound=60, memo='基板サイズ Y')
52
+ # Add design variables (Use variable names set in Femtet) to the optimization problem.
53
+ femopt.add_parameter("substrate_w", 40, lower_bound=22, upper_bound=40)
54
+ femopt.add_parameter("substrate_d", 60, lower_bound=33, upper_bound=60)
53
55
 
54
- # 目的関数の設定
55
- femopt.add_objective(max_temperature, name='メインチップ温度', args=('MAINCHIP',))
56
- femopt.add_objective(max_temperature, name='サブチップ温度', args=('SUBCHIP',))
57
- femopt.add_objective(substrate_size, name='基板サイズ')
56
+ # Add objective to the optimization problem.
57
+ femopt.add_objective(max_temperature, name='main chip temp.', args=('MAINCHIP',))
58
+ femopt.add_objective(max_temperature, name='sub chip temp.', args=('SUBCHIP',))
59
+ femopt.add_objective(substrate_size, name='substrate size')
58
60
 
59
- # 最適化の実行
61
+ # Run optimization.
60
62
  femopt.set_random_seed(42)
61
63
  femopt.optimize(n_trials=20)
62
64
  femopt.terminate_all()
pyfemtet/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.4.1"
1
+ __version__ = "0.4.3"
@@ -374,7 +374,6 @@ class History:
374
374
  prm_names = []
375
375
  obj_names = []
376
376
  cns_names = []
377
- local_data = pd.DataFrame()
378
377
  is_restart = False
379
378
  is_processing = False
380
379
  _future = None
@@ -397,6 +396,9 @@ class History:
397
396
  self.cns_names = cns_names
398
397
  self.additional_metadata = additional_metadata or ''
399
398
 
399
+ # 初期化
400
+ self.local_data = pd.DataFrame()
401
+
400
402
  # 最適化実行中かどうか
401
403
  self.is_processing = client is not None
402
404
 
@@ -0,0 +1,132 @@
1
+ """External CAD (NX) Integration
2
+
3
+ Using Femtet's stress analysis solver and Siemens' CAD software NX,
4
+ design a lightweight and high-strength H-shaped beam.
5
+
6
+ As a preliminary step, please perform the following procedures:
7
+ - Install NX
8
+ - Create a C:\temp folder
9
+ - Note: NX will save a .x_t file in this folder.
10
+ - Place the following files in the same folder:
11
+ - cad_ex01_NX.py (this file)
12
+ - cad_ex01_NX.prt
13
+ - cad_ex01_NX.femprj
14
+ """
15
+
16
+ import os
17
+
18
+ from win32com.client import constants
19
+
20
+ from pyfemtet.opt import FEMOpt
21
+ from pyfemtet.opt.interface import FemtetWithNXInterface
22
+ from pyfemtet.core import ModelError
23
+
24
+
25
+ here, me = os.path.split(__file__)
26
+ os.chdir(here)
27
+
28
+
29
+ def von_mises(Femtet):
30
+ """Obtain the maximum von Mises stress of the model.
31
+
32
+ Note:
33
+ The objective or constraint function should take Femtet
34
+ as its first argument and return a float as the output.
35
+
36
+ Warning:
37
+ CAD integration may assign boundary conditions to unintended locations.
38
+
39
+ In this example, if the boundary conditions are assigned as intended,
40
+ the maximum z displacement is always negative.
41
+ If the maximum displacement is not negative, it is assumed that
42
+ boundary condition assignment has failed.
43
+ Then this function raises a ModelError.
44
+
45
+ If a ModelError, MeshError, or SolveError occurs during optimization,
46
+ the optimization process considers the attempt a failure and skips to
47
+ the next trial.
48
+ """
49
+
50
+ # Simple check for the correctness of boundary conditions.
51
+ dx, dy, dz = Femtet.Gogh.Galileo.GetMaxDisplacement_py()
52
+ if dz >= 0:
53
+ raise ModelError('Assigning unintended boundary conditions.')
54
+
55
+ # Von Mises stress calculation.
56
+ Gogh = Femtet.Gogh
57
+ Gogh.Galileo.Potential = constants.GALILEO_VON_MISES_C
58
+ succeed, (x, y, z), mises = Gogh.Galileo.GetMAXPotentialPoint_py(constants.CMPX_REAL_C)
59
+
60
+ return mises
61
+
62
+
63
+ def mass(Femtet):
64
+ """Obtain model mass."""
65
+ return Femtet.Gogh.Galileo.GetMass('H_beam')
66
+
67
+
68
+ def C_minus_B(Femtet, opt):
69
+ """Calculate the difference between C and B dimensions.
70
+
71
+ Another example uses the following snippet to access design variables:
72
+
73
+ A = Femtet.GetVariableValue('A')
74
+
75
+ However, when performing CAD integration, this method does not work
76
+ because the variables are not set in the .femprj file.
77
+
78
+ In CAD integration, design variables are obtained in the following way.
79
+
80
+ # How to obtain a dictionary with the variable names of parameters
81
+ # added by add_parameter() as keys.
82
+ params: dict = opt.get_parameter()
83
+ A = params['A']
84
+
85
+ Or
86
+
87
+ # How to obtain an array of values of parameters added in the order
88
+ # by add_parameter().
89
+ values: np.ndarray = opt.get_parameter('values')
90
+ A, B, C = values
91
+
92
+ Objective functions and constraint functions can take arbitrary variables
93
+ after the first argument.
94
+ The FEMOpt member variable `opt` has a method called get_parameter().
95
+ This method allows you to retrieve design variables added by add_parameter().
96
+ By taking `opt` as the second argument, you can execute get_parameter()
97
+ within the objective or constraint function to retrieve design variables.
98
+ """
99
+ A, B, C = opt.get_parameter('values')
100
+ return C - B
101
+
102
+
103
+ if __name__ == '__main__':
104
+
105
+ # Initialize NX-Femtet integration object.
106
+ # At this point, Python is connected to the Femtet.
107
+ fem = FemtetWithNXInterface(
108
+ prt_path='cad_ex01_NX.prt',
109
+ open_result_with_gui=False, # To calculate von Mises stress, set this argument to False. See Femtet Macro Help.
110
+ )
111
+
112
+ # Initialize the FEMOpt object.
113
+ # (establish connection between the optimization problem and Femtet)
114
+ femopt = FEMOpt(fem=fem)
115
+
116
+ # Add design variables to the optimization problem.
117
+ # (Specify the variables registered in the femprj file.)
118
+ femopt.add_parameter('A', 10, lower_bound=1, upper_bound=59)
119
+ femopt.add_parameter('B', 10, lower_bound=1, upper_bound=40)
120
+ femopt.add_parameter('C', 20, lower_bound=5, upper_bound=59)
121
+
122
+ # Add the constraint function to the optimization problem.
123
+ femopt.add_constraint(C_minus_B, 'C>B', lower_bound=1, args=femopt.opt)
124
+
125
+ # Add the objective function to the optimization problem.
126
+ femopt.add_objective(von_mises, name='von Mises (Pa)')
127
+ femopt.add_objective(mass, name='mass (kg)')
128
+
129
+ # Run optimization.
130
+ femopt.set_random_seed(42)
131
+ femopt.optimize(n_trials=20)
132
+ femopt.terminate_all()
@@ -0,0 +1,132 @@
1
+ """External CAD (SOLIDWORKS) Integration
2
+
3
+ Using Femtet's stress analysis solver and Dassault Systemes' CAD software SOLIDWORKS,
4
+ design a lightweight and high-strength H-shaped beam.
5
+
6
+ As a preliminary step, please perform the following procedures:
7
+ - Install SOLIDWORKS
8
+ - Create a C:\temp folder
9
+ - Note: SOLIDWORKS will save a .x_t file in this folder.
10
+ - Place the following files in the same folder:
11
+ - cad_ex01_SW.py (this file)
12
+ - cad_ex01_SW.SLDPRT
13
+ - cad_ex01_SW.femprj
14
+ """
15
+
16
+ import os
17
+
18
+ from win32com.client import constants
19
+
20
+ from pyfemtet.opt import FEMOpt
21
+ from pyfemtet.opt.interface import FemtetWithSolidworksInterface
22
+ from pyfemtet.core import ModelError
23
+
24
+
25
+ here, me = os.path.split(__file__)
26
+ os.chdir(here)
27
+
28
+
29
+ def von_mises(Femtet):
30
+ """Obtain the maximum von Mises stress of the model.
31
+
32
+ Note:
33
+ The objective or constraint function should take Femtet
34
+ as its first argument and return a float as the output.
35
+
36
+ Warning:
37
+ CAD integration may assign boundary conditions to unintended locations.
38
+
39
+ In this example, if the boundary conditions are assigned as intended,
40
+ the maximum z displacement is always negative.
41
+ If the maximum displacement is not negative, it is assumed that
42
+ boundary condition assignment has failed.
43
+ Then this function raises a ModelError.
44
+
45
+ If a ModelError, MeshError, or SolveError occurs during optimization,
46
+ the optimization process considers the attempt a failure and skips to
47
+ the next trial.
48
+ """
49
+
50
+ # Simple check for the correctness of boundary conditions.
51
+ dx, dy, dz = Femtet.Gogh.Galileo.GetMaxDisplacement_py()
52
+ if dz >= 0:
53
+ raise ModelError('Assigning unintended boundary conditions.')
54
+
55
+ # Von Mises stress calculation.
56
+ Gogh = Femtet.Gogh
57
+ Gogh.Galileo.Potential = constants.GALILEO_VON_MISES_C
58
+ succeed, (x, y, z), mises = Gogh.Galileo.GetMAXPotentialPoint_py(constants.CMPX_REAL_C)
59
+
60
+ return mises
61
+
62
+
63
+ def mass(Femtet):
64
+ """Obtain model mass."""
65
+ return Femtet.Gogh.Galileo.GetMass('H_beam')
66
+
67
+
68
+ def C_minus_B(Femtet, opt):
69
+ """Calculate the difference between C and B dimensions.
70
+
71
+ Another example uses the following snippet to access design variables:
72
+
73
+ A = Femtet.GetVariableValue('A')
74
+
75
+ However, when performing CAD integration, this method does not work
76
+ because the variables are not set in the .femprj file.
77
+
78
+ In CAD integration, design variables are obtained in the following way.
79
+
80
+ # How to obtain a dictionary with the variable names of parameters
81
+ # added by add_parameter() as keys.
82
+ params: dict = opt.get_parameter()
83
+ A = params['A']
84
+
85
+ Or
86
+
87
+ # How to obtain an array of values of parameters added in the order
88
+ # by add_parameter().
89
+ values: np.ndarray = opt.get_parameter('values')
90
+ A, B, C = values
91
+
92
+ Objective functions and constraint functions can take arbitrary variables
93
+ after the first argument.
94
+ The FEMOpt member variable `opt` has a method called get_parameter().
95
+ This method allows you to retrieve design variables added by add_parameter().
96
+ By taking `opt` as the second argument, you can execute get_parameter()
97
+ within the objective or constraint function to retrieve design variables.
98
+ """
99
+ A, B, C = opt.get_parameter('values')
100
+ return C - B
101
+
102
+
103
+ if __name__ == '__main__':
104
+
105
+ # Initialize NX-Femtet integration object.
106
+ # At this point, Python is connected to the Femtet.
107
+ fem = FemtetWithSolidworksInterface(
108
+ sldprt_path='cad_ex01_SW.SLDPRT',
109
+ open_result_with_gui=False, # To calculate von Mises stress, set this argument to False. See Femtet Macro Help.
110
+ )
111
+
112
+ # Initialize the FEMOpt object.
113
+ # (establish connection between the optimization problem and Femtet)
114
+ femopt = FEMOpt(fem=fem)
115
+
116
+ # Add design variables to the optimization problem.
117
+ # (Specify the variables registered in the femprj file.)
118
+ femopt.add_parameter('A', 10, lower_bound=1, upper_bound=59)
119
+ femopt.add_parameter('B', 10, lower_bound=1, upper_bound=40)
120
+ femopt.add_parameter('C', 20, lower_bound=5, upper_bound=59)
121
+
122
+ # Add the constraint function to the optimization problem.
123
+ femopt.add_constraint(C_minus_B, 'C>B', lower_bound=1, args=femopt.opt)
124
+
125
+ # Add the objective function to the optimization problem.
126
+ femopt.add_objective(von_mises, name='von Mises (Pa)')
127
+ femopt.add_objective(mass, name='mass (kg)')
128
+
129
+ # Run optimization.
130
+ femopt.set_random_seed(42)
131
+ femopt.optimize(n_trials=20)
132
+ femopt.terminate_all()