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
@@ -0,0 +1,75 @@
1
+ """Single-objective optimization: bending with consideration for springback.
2
+
3
+ Using Femtet's stress analysis solver, we will determine the bending angle
4
+ to achieve the desired material bend angle with consideration for springback.
5
+ Elasto-plastic analysis is available in an optional package.
6
+
7
+ Corresponding project: gal_ex58_parametric.femprj
8
+ """
9
+ import numpy as np
10
+ from win32com.client import constants
11
+ from optuna.integration.botorch import BoTorchSampler
12
+
13
+ from pyfemtet.opt import FEMOpt, OptunaOptimizer
14
+
15
+
16
+ def bending(Femtet):
17
+ """Get the material bend angle.
18
+
19
+ Note:
20
+ The objective or constraint function should take Femtet
21
+ as its first argument and return a float as the output.
22
+
23
+ Params:
24
+ Femtet: This is an instance for manipulating Femtet with macros. For detailed information, please refer to "Femtet Macro Help".
25
+
26
+ Returns:
27
+ float: material bend angle.
28
+ """
29
+ Gogh = Femtet.Gogh
30
+
31
+ # Set the mode after unloading.
32
+ Gogh.Galileo.Mode = Gogh.Galileo.nMode - 1
33
+
34
+ # Obtain the displacement of the measurement target point.
35
+ Gogh.Galileo.Vector = constants.GALILEO_DISPLACEMENT_C
36
+ succeed, (x, y, z) = Gogh.Galileo.GetVectorAtPoint_py(200, 0, 0)
37
+
38
+ # Calculate the angle formed by the line segment
39
+ # connecting the bending origin (100, 0) and the
40
+ # deformed point with the X-axis.
41
+ bending_point = np.array((100, 0))
42
+ bended_point = np.array((200 + 1000 * x.Real, 1000 * z.Real))
43
+ dx, dz = bended_point - bending_point
44
+ degree = np.arctan2(-dz, dx)
45
+
46
+ return degree * 360 / (2*np.pi) # unit: degree
47
+
48
+
49
+ if __name__ == '__main__':
50
+
51
+ # Initialize the numerical optimization problem.
52
+ # (determine the optimization method)
53
+ opt = OptunaOptimizer(
54
+ sampler_class=BoTorchSampler,
55
+ sampler_kwargs=dict(
56
+ n_startup_trials=3,
57
+ )
58
+ )
59
+
60
+ # Initialize the FEMOpt object.
61
+ # (establish connection between the optimization problem and Femtet)
62
+ femopt = FEMOpt(opt=opt)
63
+
64
+ # Add design variables to the optimization problem.
65
+ # (Specify the variables registered in the femprj file.)
66
+ femopt.add_parameter("rot", 90, lower_bound=80, upper_bound=100)
67
+
68
+ # Add the objective function to the optimization problem.
69
+ # The target bending angle is 90 degrees.
70
+ femopt.add_objective(bending, name='final angle (degree)', direction=90)
71
+
72
+ # Run optimization.
73
+ femopt.set_random_seed(42)
74
+ femopt.optimize(n_trials=10)
75
+ femopt.terminate_all()
@@ -0,0 +1,59 @@
1
+ """Single-objective optimization: Self-inductance of a finite-length helical coil.
2
+
3
+ Using Femtet's magnetic field analysis solver, design to achieve
4
+ the target value for the self-inductance of a finite-length helical coil.
5
+
6
+ Corresponding project: gau_ex08_parametric.femprj
7
+ """
8
+ from optuna.integration.botorch import BoTorchSampler
9
+ from pyfemtet.opt import FEMOpt, OptunaOptimizer
10
+
11
+
12
+ def inductance(Femtet):
13
+ """Obtain the self-inductance.
14
+
15
+ Note:
16
+ The objective or constraint function should take Femtet
17
+ as its first argument and return a float as the output.
18
+
19
+ Params:
20
+ Femtet: This is an instance for manipulating Femtet with macros. For detailed information, please refer to "Femtet Macro Help".
21
+
22
+ Returns:
23
+ float: Self-inductance.
24
+ """
25
+ Gogh = Femtet.Gogh
26
+
27
+ coil_name = Gogh.Gauss.GetCoilList()[0]
28
+ return Gogh.Gauss.GetL(coil_name, coil_name) # unit: F
29
+
30
+
31
+ if __name__ == '__main__':
32
+
33
+ # Initialize the numerical optimization problem.
34
+ # (determine the optimization method)
35
+ opt = OptunaOptimizer(
36
+ sampler_class=BoTorchSampler,
37
+ sampler_kwargs=dict(
38
+ n_startup_trials=5,
39
+ )
40
+ )
41
+
42
+ # Initialize the FEMOpt object.
43
+ # (establish connection between the optimization problem and Femtet)
44
+ femopt = FEMOpt(opt=opt)
45
+
46
+ # Add design variables to the optimization problem.
47
+ # (Specify the variables registered in the femprj file.)
48
+ femopt.add_parameter("helical_pitch", 6, lower_bound=4.2, upper_bound=8)
49
+ femopt.add_parameter("coil_radius", 10, lower_bound=1, upper_bound=10)
50
+ femopt.add_parameter("n_turns", 5, lower_bound=1, upper_bound=5)
51
+
52
+ # Add the objective function to the optimization problem.
53
+ # The target inductance is 0.1 uF.
54
+ femopt.add_objective(inductance, name='self-inductance (F)', direction=1e-7)
55
+
56
+ # Run optimization.
57
+ femopt.set_random_seed(42)
58
+ femopt.optimize(n_trials=20)
59
+ femopt.terminate_all()
@@ -0,0 +1,137 @@
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
+
7
+ Corresponding project: her_ex40_parametric.femprj
8
+ """
9
+ from time import sleep
10
+
11
+ import numpy as np
12
+ from scipy.signal import find_peaks
13
+ from tqdm import tqdm
14
+ from optuna.integration.botorch import BoTorchSampler
15
+
16
+ from pyfemtet.core import SolveError
17
+ from pyfemtet.opt import OptunaOptimizer, FEMOpt
18
+
19
+
20
+ class SParameterCalculator:
21
+ """Calculating S-parameters and resonance frequencies."""
22
+
23
+ def __init__(self):
24
+ self.freq = []
25
+ self.S = []
26
+ self.interpolated_function = None
27
+ self.resonance_frequency = None
28
+ self.minimum_S = None
29
+
30
+ def _get_freq_and_S_parameter(self, Femtet):
31
+ """Obtain the relationship between frequency and S-parameter"""
32
+
33
+ Gogh = Femtet.Gogh
34
+
35
+ freq_list = []
36
+ dB_S_list = []
37
+ for mode in tqdm(range(Gogh.Hertz.nMode), 'Obtain frequency and S-parameter.'):
38
+ # mode setting
39
+ Gogh.Hertz.Mode = mode
40
+ sleep(0.01)
41
+
42
+ # Obtain frequency
43
+ freq = Gogh.Hertz.GetFreq().Real
44
+
45
+ # Obtain S(1, 1)
46
+ comp_S = Gogh.Hertz.GetSMatrix(0, 0)
47
+ norm = np.linalg.norm((comp_S.Real, comp_S.Imag))
48
+ dB_S = 20 * np.log10(norm)
49
+
50
+ # Save them
51
+ freq_list.append(freq)
52
+ dB_S_list.append(dB_S)
53
+
54
+ self.freq = freq_list
55
+ self.S = dB_S_list
56
+
57
+ def _calc_resonance_frequency(self):
58
+ """Compute the frequency that gives the first peak for S-parameter."""
59
+ peaks, _ = find_peaks(-np.array(self.S), height=None, threshold=None, distance=None, prominence=0.5, width=None, wlen=None, rel_height=0.5, plateau_size=None)
60
+ if len(peaks) == 0:
61
+ raise SolveError('No S(1,1) peaks detected.')
62
+ self.resonance_frequency = self.freq[peaks[0]]
63
+ self.minimum_S = self.S[peaks[0]]
64
+
65
+ def get_resonance_frequency(self, Femtet):
66
+ """Calculate the resonant frequency.
67
+
68
+ Note:
69
+ The objective or constraint function should take Femtet
70
+ as its first argument and return a float as the output.
71
+
72
+ Params:
73
+ Femtet: This is an instance for manipulating Femtet with macros. For detailed information, please refer to "Femtet Macro Help".
74
+
75
+ Returns:
76
+ float: A resonance frequency of the antenna.
77
+ """
78
+ self._get_freq_and_S_parameter(Femtet)
79
+ self._calc_resonance_frequency()
80
+ return self.resonance_frequency # unit: Hz
81
+
82
+
83
+ def antenna_is_smaller_than_substrate(Femtet):
84
+ """Calculate the relationship between antenna size and board size.
85
+
86
+ This function is used to constrain the model
87
+ from breaking down while changing parameters.
88
+
89
+ Returns:
90
+ float: Difference between the substrate size and antenna size. Must be equal to or grater than 1 mm.
91
+ """
92
+ r = Femtet.GetVariableValue('antenna_radius')
93
+ w = Femtet.GetVariableValue('substrate_w')
94
+ return w / 2 - r # unit: mm
95
+
96
+
97
+ def port_is_inside_antenna(Femtet):
98
+ """Calculate the relationship between the feed port location and antenna size."""
99
+ r = Femtet.GetVariableValue('antenna_radius')
100
+ x = Femtet.GetVariableValue('port_x')
101
+ return r - x # unit: mm. Must be equal to or grater than 1 mm.
102
+
103
+
104
+ if __name__ == '__main__':
105
+ # Initialize the object for calculating frequency characteristics.
106
+ s = SParameterCalculator()
107
+
108
+ # Initialize the numerical optimization problem.
109
+ # (determine the optimization method)
110
+ opt = OptunaOptimizer(
111
+ sampler_class=BoTorchSampler,
112
+ sampler_kwargs=dict(
113
+ n_startup_trials=10,
114
+ )
115
+ )
116
+
117
+ # Initialize the FEMOpt object.
118
+ # (establish connection between the optimization problem and Femtet)
119
+ femopt = FEMOpt(opt=opt)
120
+
121
+ # Add design variables to the optimization problem.
122
+ # (Specify the variables registered in the femprj file.)
123
+ femopt.add_parameter('antenna_radius', 10, 5, 20)
124
+ femopt.add_parameter('substrate_w', 50, 40, 60)
125
+ femopt.add_parameter('port_x', 5, 1, 20)
126
+
127
+ # Add the constraint function to the optimization problem.
128
+ femopt.add_constraint(antenna_is_smaller_than_substrate, 'antenna and substrate clearance', lower_bound=1)
129
+ femopt.add_constraint(port_is_inside_antenna, 'antenna and port clearance', lower_bound=1)
130
+
131
+ # Add the objective function to the optimization problem.
132
+ # The target frequency is 3.0 GHz.
133
+ femopt.add_objective(s.get_resonance_frequency, 'first resonant frequency(Hz)', direction=3.0 * 1e9)
134
+
135
+ femopt.set_random_seed(42)
136
+ femopt.optimize(n_trials=15)
137
+ femopt.terminate_all()
@@ -0,0 +1,61 @@
1
+ """Multi-objective optimization: Air cooling of IC on a printed circuit board (forced convection).
2
+
3
+ Using Femtet's simple fluid-thermal analysis solver,
4
+ design a solution that reduces the chip temperature
5
+ while minimizing the substrate size.
6
+
7
+ Related project: paswat_ex1_parametric.femprj
8
+ """
9
+ from pyfemtet.opt import FEMOpt
10
+
11
+
12
+ def chip_temp(Femtet, chip_name):
13
+ """Obtain the maximum temperature of the chip.
14
+
15
+ Note:
16
+ The objective or constraint function should take Femtet
17
+ as its first argument and return a float as the output.
18
+
19
+ Params:
20
+ Femtet: An instance for manipulating Femtet with macros. For detailed information, please refer to "Femtet Macro Help".
21
+ chip_name (str): The body attribute name defined in femprj. Valid values are 'MAINCHIP' or 'SUBCHIP'.
22
+
23
+ Returns:
24
+ float: The maximum temperature of the body with the specified body attribute name.
25
+ """
26
+ Gogh = Femtet.Gogh
27
+
28
+ max_temperature, min_temperature, mean_temperature = Gogh.Watt.GetTemp(chip_name)
29
+
30
+ return max_temperature # unit: degree
31
+
32
+
33
+ def substrate_size(Femtet):
34
+ """Calculate the occupied area on the XY plane of the substrate."""
35
+ substrate_w = Femtet.GetVariableValue('substrate_w')
36
+ substrate_d = Femtet.GetVariableValue('substrate_d')
37
+ return substrate_w * substrate_d # unit: mm2
38
+
39
+
40
+ if __name__ == '__main__':
41
+
42
+ # Initialize the FEMOpt object.
43
+ # (establish connection between the optimization problem and Femtet)
44
+ femopt = FEMOpt()
45
+
46
+ # Add design variables to the optimization problem.
47
+ # (Specify the variables registered in the femprj file.)
48
+ femopt.add_parameter("substrate_w", 40, lower_bound=22, upper_bound=60)
49
+ femopt.add_parameter("substrate_d", 60, lower_bound=34, upper_bound=60)
50
+ femopt.add_parameter("rot", 0, lower_bound=0, upper_bound=180)
51
+
52
+ # Add the objective function to the optimization problem.
53
+ # The target bending angle is 90 degrees.
54
+ femopt.add_objective(chip_temp, name='max temp. of<br>MAINCHIP (degree)', direction='minimize', args=('MAINCHIP',))
55
+ femopt.add_objective(chip_temp, name='max temp. of<br>SUBCHIP (degree)', direction='minimize', args=('SUBCHIP',))
56
+ femopt.add_objective(substrate_size, name='substrate size (mm2)', direction='minimize')
57
+
58
+ # Run optimization.
59
+ femopt.set_random_seed(42)
60
+ femopt.optimize(n_trials=15)
61
+ femopt.terminate_all()
@@ -0,0 +1,62 @@
1
+ """Multi-objective optimization: Air cooling of IC on a printed circuit board (forced convection).
2
+
3
+ Using Femtet's simple fluid-thermal analysis solver,
4
+ design a solution that reduces the chip temperature
5
+ while minimizing the substrate size.
6
+
7
+ Related project: paswat_ex1_parametric.femprj
8
+ """
9
+ from pyfemtet.opt import FEMOpt
10
+
11
+
12
+ def chip_temp(Femtet, chip_name):
13
+ """Obtain the maximum temperature of the chip.
14
+
15
+ Note:
16
+ The objective or constraint function should take Femtet
17
+ as its first argument and return a float as the output.
18
+
19
+ Params:
20
+ Femtet: An instance for manipulating Femtet with macros. For detailed information, please refer to "Femtet Macro Help".
21
+ chip_name (str): The body attribute name defined in femprj. Valid values are 'MAINCHIP' or 'SUBCHIP'.
22
+
23
+ Returns:
24
+ float: The maximum temperature of the body with the specified body attribute name.
25
+ """
26
+ Gogh = Femtet.Gogh
27
+
28
+ max_temperature, min_temperature, mean_temperature = Gogh.Watt.GetTemp(chip_name)
29
+
30
+ return max_temperature # unit: degree
31
+
32
+
33
+ def substrate_size(Femtet):
34
+ """Calculate the occupied area on the XY plane of the substrate."""
35
+ substrate_w = Femtet.GetVariableValue('substrate_w')
36
+ substrate_d = Femtet.GetVariableValue('substrate_d')
37
+ return substrate_w * substrate_d # unit: mm2
38
+
39
+
40
+ if __name__ == '__main__':
41
+
42
+ # Initialize the FEMOpt object.
43
+ # (establish connection between the optimization problem and Femtet)
44
+ femopt = FEMOpt()
45
+
46
+ # Add design variables to the optimization problem.
47
+ # (Specify the variables registered in the femprj file.)
48
+ femopt.add_parameter("substrate_w", 40, lower_bound=22, upper_bound=60)
49
+ femopt.add_parameter("substrate_d", 60, lower_bound=34, upper_bound=60)
50
+ femopt.add_parameter("rot", 0, lower_bound=0, upper_bound=180)
51
+
52
+ # Add the objective function to the optimization problem.
53
+ # The target bending angle is 90 degrees.
54
+ femopt.add_objective(chip_temp, name='max temp. of<br>MAINCHIP (degree)', direction='minimize', args=('MAINCHIP',))
55
+ femopt.add_objective(chip_temp, name='max temp. of<br>SUBCHIP (degree)', direction='minimize', args=('SUBCHIP',))
56
+ femopt.add_objective(substrate_size, name='substrate size (mm2)', direction='minimize')
57
+
58
+ # Run optimization.
59
+ femopt.set_random_seed(42)
60
+ # femopt.optimize(n_trials=15)
61
+ femopt.optimize(n_trials=30, n_parallel=3) # This line is the only difference with no parallel pattern.
62
+ femopt.terminate_all()
@@ -0,0 +1,59 @@
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)
59
+ femopt.terminate_all()
@@ -0,0 +1,126 @@
1
+ """外部 CAD (NX) 連携
2
+
3
+ Femtet の応力解析ソルバ、および
4
+ Siemens 社製 CAD ソフト NX を用いて
5
+ 軽量かつ高剛性な H 型鋼の設計を行います。
6
+
7
+ 事前準備として、下記の手順を実行してください。
8
+ - NX のインストール
9
+ - C:\temp フォルダを作成する
10
+ - Note: NX が .x_t ファイルをこのフォルダに保存します。
11
+ - 以下のファイルを同じフォルダに配置
12
+ - cad_ex01_NX_jp.py (このファイル)
13
+ - cad_ex01_NX.prt
14
+ - cad_ex01_NX_jp.femprj
15
+ """
16
+
17
+ import os
18
+
19
+ from win32com.client import constants
20
+
21
+ from pyfemtet.opt import FEMOpt
22
+ from pyfemtet.opt.interface import FemtetWithNXInterface
23
+ from pyfemtet.core import ModelError
24
+
25
+
26
+ here, me = os.path.split(__file__)
27
+ os.chdir(here)
28
+
29
+
30
+ def von_mises(Femtet):
31
+ """モデルの最大フォン・ミーゼス応力を取得します。
32
+
33
+ Note:
34
+ 目的関数または制約関数は、
35
+ 第一引数としてFemtetを受け取り、
36
+ 戻り値としてfloat型を返す必要があります。
37
+
38
+ Warning:
39
+ CAD 連携機能では、意図しない位置に境界条件が設定される可能性があります。
40
+
41
+ この例では、境界条件が意図したとおりに割り当てられている場合、
42
+ 最大変位は常に負になります。最大変位が正の場合、境界条件の割り当てが
43
+ 失敗したとみなし、ModelError を送出します。
44
+
45
+ 最適化中に ModelError、MeshError、または SolveError が発生した場合、
46
+ 最適化プロセスは試行を失敗とみなし、次のトライアルにスキップします。
47
+ """
48
+
49
+ # 簡易的な境界条件の正しさチェック
50
+ dx, dy, dz = Femtet.Gogh.Galileo.GetMaxDisplacement_py()
51
+ if dz >= 0:
52
+ raise ModelError('境界条件の設定が間違っています。')
53
+
54
+ # ミーゼス応力計算
55
+ Gogh = Femtet.Gogh
56
+ Gogh.Galileo.Potential = constants.GALILEO_VON_MISES_C
57
+ succeed, (x, y, z), mises = Gogh.Galileo.GetMAXPotentialPoint_py(constants.CMPX_REAL_C)
58
+
59
+ return mises
60
+
61
+
62
+ def mass(Femtet):
63
+ """モデルの質量を取得します。"""
64
+ return Femtet.Gogh.Galileo.GetMass('H_beam')
65
+
66
+
67
+ def C_minus_B(Femtet, opt):
68
+ """C 寸法と B 寸法の差を計算します。
69
+
70
+ 別の例では、次のスニペットを使用して設計変数にアクセスします。
71
+
72
+ A = Femtet.GetVariableValue('A')
73
+
74
+ ただし、CAD 連携機能を使用する場合、設計変数が .femprj ファイルに
75
+ 設定されていないため、この方法は機能しません。
76
+
77
+ CAD 連携機能を使用する場合、以下の方法で設計変数にアクセスすることができます。
78
+
79
+ # add_parameter() で追加したパラメータの変数名をキーとする辞書を得る方法
80
+ params: dict = opt.get_parameter()
81
+ A = params['A']
82
+
83
+ 又は
84
+
85
+ # add_parameter() で追加した順のパラメータの値の配列を得る方法
86
+ values: np.ndarray = opt.get_parameter('values')
87
+ A, B, C = values
88
+
89
+ 目的関数と拘束関数は、最初の引数の後に任意の変数を取ることができます。
90
+ FEMOpt のメンバ変数 opt には get_parameter() というメソッドがあります。
91
+ このメソッドによって add_parameter() で追加された設計変数を取得できます。
92
+ opt を第 2 引数として取ることにより、目的関数または拘束関数内で
93
+ get_parameter() を実行して設計変数を取得できます。
94
+ """
95
+ A, B, C = opt.get_parameter('values')
96
+ return C - B
97
+
98
+
99
+ if __name__ == '__main__':
100
+
101
+ # NX-Femtet 連携オブジェクトの初期化
102
+ # この処理により、Python プロセスは Femtet に接続を試みます。
103
+ fem = FemtetWithNXInterface(
104
+ prt_path='cad_ex01_NX.prt',
105
+ open_result_with_gui=False,
106
+ )
107
+
108
+ # FEMOpt オブジェクトの初期化 (最適化問題とFemtetとの接続を行います)
109
+ femopt = FEMOpt(fem=fem)
110
+
111
+ # 設計変数を最適化問題に追加 (femprj ファイルに登録されている変数を指定してください)
112
+ femopt.add_parameter('A', 10, lower_bound=1, upper_bound=59)
113
+ femopt.add_parameter('B', 10, lower_bound=1, upper_bound=40)
114
+ femopt.add_parameter('C', 20, lower_bound=5, upper_bound=59)
115
+
116
+ # 拘束関数を最適化問題に追加
117
+ femopt.add_constraint(C_minus_B, 'C>B', lower_bound=1, args=femopt.opt)
118
+
119
+ # 目的関数を最適化問題に追加
120
+ femopt.add_objective(von_mises, name='von Mises (Pa)')
121
+ femopt.add_objective(mass, name='mass (kg)')
122
+
123
+ # 最適化を実行
124
+ femopt.set_random_seed(42)
125
+ femopt.optimize(n_trials=20)
126
+ femopt.terminate_all()