pyfemtet 0.3.12__tar.gz → 0.4.2__tar.gz

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 (47) hide show
  1. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/PKG-INFO +6 -5
  2. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/README.md +2 -1
  3. pyfemtet-0.4.2/pyfemtet/FemtetPJTSample/NX_ex01/NX_ex01.py +118 -0
  4. pyfemtet-0.4.2/pyfemtet/FemtetPJTSample/Sldworks_ex01/Sldworks_ex01.py +121 -0
  5. pyfemtet-0.4.2/pyfemtet/FemtetPJTSample/gau_ex08_parametric.py +58 -0
  6. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/FemtetPJTSample/her_ex40_parametric.femprj +0 -0
  7. pyfemtet-0.4.2/pyfemtet/FemtetPJTSample/her_ex40_parametric.py +148 -0
  8. pyfemtet-0.4.2/pyfemtet/FemtetPJTSample/wat_ex14_parallel_parametric.py +65 -0
  9. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/FemtetPJTSample/wat_ex14_parametric.femprj +0 -0
  10. pyfemtet-0.4.2/pyfemtet/FemtetPJTSample/wat_ex14_parametric.py +64 -0
  11. pyfemtet-0.4.2/pyfemtet/__init__.py +1 -0
  12. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/core.py +14 -0
  13. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/dispatch_extensions.py +5 -0
  14. pyfemtet-0.4.2/pyfemtet/opt/__init__.py +22 -0
  15. pyfemtet-0.4.2/pyfemtet/opt/_femopt.py +544 -0
  16. pyfemtet-0.4.2/pyfemtet/opt/_femopt_core.py +732 -0
  17. pyfemtet-0.4.2/pyfemtet/opt/interface/__init__.py +15 -0
  18. pyfemtet-0.4.2/pyfemtet/opt/interface/_base.py +71 -0
  19. pyfemtet-0.3.12/pyfemtet/opt/interface.py → pyfemtet-0.4.2/pyfemtet/opt/interface/_femtet.py +121 -408
  20. pyfemtet-0.4.2/pyfemtet/opt/interface/_femtet_with_nx/__init__.py +3 -0
  21. pyfemtet-0.4.2/pyfemtet/opt/interface/_femtet_with_nx/_interface.py +128 -0
  22. pyfemtet-0.4.2/pyfemtet/opt/interface/_femtet_with_sldworks.py +174 -0
  23. pyfemtet-0.4.2/pyfemtet/opt/opt/__init__.py +8 -0
  24. pyfemtet-0.4.2/pyfemtet/opt/opt/_base.py +202 -0
  25. pyfemtet-0.4.2/pyfemtet/opt/opt/_optuna.py +246 -0
  26. pyfemtet-0.4.2/pyfemtet/opt/visualization/__init__.py +7 -0
  27. pyfemtet-0.4.2/pyfemtet/opt/visualization/_graphs.py +222 -0
  28. pyfemtet-0.4.2/pyfemtet/opt/visualization/_monitor.py +1149 -0
  29. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyproject.toml +9 -3
  30. pyfemtet-0.3.12/pyfemtet/FemtetPJTSample/NX_ex01/NX_ex01.py +0 -89
  31. pyfemtet-0.3.12/pyfemtet/FemtetPJTSample/Sldworks_ex01/Sldworks_ex01.py +0 -99
  32. pyfemtet-0.3.12/pyfemtet/FemtetPJTSample/gau_ex08_parametric.py +0 -55
  33. pyfemtet-0.3.12/pyfemtet/FemtetPJTSample/her_ex40_parametric.py +0 -136
  34. pyfemtet-0.3.12/pyfemtet/FemtetPJTSample/wat_ex14_parallel_parametric.py +0 -63
  35. pyfemtet-0.3.12/pyfemtet/FemtetPJTSample/wat_ex14_parametric.py +0 -62
  36. pyfemtet-0.3.12/pyfemtet/__init__.py +0 -1
  37. pyfemtet-0.3.12/pyfemtet/opt/__init__.py +0 -2
  38. pyfemtet-0.3.12/pyfemtet/opt/base.py +0 -1490
  39. pyfemtet-0.3.12/pyfemtet/opt/monitor.py +0 -474
  40. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/LICENSE +0 -0
  41. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/FemtetPJTSample/NX_ex01/NX_ex01.femprj +0 -0
  42. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/FemtetPJTSample/NX_ex01/NX_ex01.prt +0 -0
  43. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/FemtetPJTSample/Sldworks_ex01/Sldworks_ex01.SLDPRT +0 -0
  44. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/FemtetPJTSample/Sldworks_ex01/Sldworks_ex01.femprj +0 -0
  45. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/FemtetPJTSample/gau_ex08_parametric.femprj +0 -0
  46. {pyfemtet-0.3.12 → pyfemtet-0.4.2}/pyfemtet/logger.py +0 -0
  47. {pyfemtet-0.3.12/pyfemtet/opt/_FemtetWithNX → pyfemtet-0.4.2/pyfemtet/opt/interface/_femtet_with_nx}/update_model.py +0 -0
@@ -1,19 +1,18 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyfemtet
3
- Version: 0.3.12
3
+ Version: 0.4.2
4
4
  Summary: Design parameter optimization using Femtet.
5
5
  Home-page: https://github.com/pyfemtet/pyfemtet
6
6
  License: BSD-3-Clause
7
7
  Author: kazuma.naito
8
8
  Author-email: kazuma.naito@murata.com
9
- Requires-Python: >=3.9,<3.13
9
+ Requires-Python: >=3.9.3,<3.13
10
10
  Classifier: License :: OSI Approved :: BSD License
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
15
14
  Classifier: Programming Language :: Python :: 3.12
16
- Requires-Dist: botorch (>=0.9.5,<0.10.0)
15
+ Requires-Dist: botorch (>=0.9.5,<0.10.0) ; python_version < "3.12"
17
16
  Requires-Dist: colorlog (>=6.8.0,<7.0.0)
18
17
  Requires-Dist: dash (>=2.14.2,<3.0.0)
19
18
  Requires-Dist: dash-bootstrap-components (>=1.5.0,<2.0.0)
@@ -23,6 +22,7 @@ Requires-Dist: femtetutils (>=1.0.0,<2.0.0)
23
22
  Requires-Dist: numpy (>=1.26.2,<2.0.0)
24
23
  Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
25
24
  Requires-Dist: optuna (>=3.4.0,<4.0.0)
25
+ Requires-Dist: optuna-integration (>=3.6.0,<4.0.0)
26
26
  Requires-Dist: pandas (>=2.1.3,<3.0.0)
27
27
  Requires-Dist: plotly (>=5.18.0,<6.0.0)
28
28
  Requires-Dist: psutil (>=5.9.6,<6.0.0)
@@ -35,7 +35,8 @@ Description-Content-Type: text/markdown
35
35
  PyFemtet is the extension package for Femtet with Python.
36
36
 
37
37
  - Femtet Website: https://www.muratasoftware.com/
38
- - Documentation: https://pyfemtet.github.io/pyfemtet/
38
+ - Documentation (English): https://pyfemtet.readthedocs.io/en/stable/
39
+ - ドキュメント(日本語): https://pyfemtet.readthedocs.io/jp/stable/
39
40
  - Source code: https://github.com/pyfemtet/pyfemtet
40
41
  - Bug reports: https://github.com/pyfemtet/pyfemtet/issues
41
42
 
@@ -1,7 +1,8 @@
1
1
  PyFemtet is the extension package for Femtet with Python.
2
2
 
3
3
  - Femtet Website: https://www.muratasoftware.com/
4
- - Documentation: https://pyfemtet.github.io/pyfemtet/
4
+ - Documentation (English): https://pyfemtet.readthedocs.io/en/stable/
5
+ - ドキュメント(日本語): https://pyfemtet.readthedocs.io/jp/stable/
5
6
  - Source code: https://github.com/pyfemtet/pyfemtet
6
7
  - Bug reports: https://github.com/pyfemtet/pyfemtet/issues
7
8
 
@@ -0,0 +1,118 @@
1
+ """External CAD (NX) Integration
2
+
3
+ This script performs parametric optimization
4
+ using a project that has imported an external CAD model
5
+ that has been parametrically modeled.
6
+
7
+ Please perform the following steps in preparation.
8
+ - Install NX.
9
+ - Place NX_ex01.prt, NX_ex01.femprj and .py file in the same folder.
10
+ - Create C:\\temp folder on your disk.
11
+ Note: NX exports .x_t files during optimization.
12
+ """
13
+
14
+ import os
15
+ from pyfemtet.opt import FEMOpt, OptunaOptimizer
16
+ from pyfemtet.opt.interface import FemtetWithNXInterface
17
+ from pyfemtet.core import ModelError
18
+
19
+
20
+ here, me = os.path.split(__file__)
21
+ os.chdir(here)
22
+
23
+
24
+ def disp(Femtet):
25
+ """Obtain the maximum displacement in the Z direction from the analysis results.
26
+
27
+ Note:
28
+ The objective or constraint function
29
+ must take a Femtet as its first argument
30
+ and must return a single float.
31
+
32
+ Warning:
33
+ CAD integration may assign boundary conditions to unintended locations.
34
+
35
+ In this example, if the boundary conditions are assigned as intended,
36
+ the maximum displacement is always negative.
37
+ If the maximum displacement is positive,
38
+ it is assumed that boundary condition assignment has failed
39
+ and a ModelError is raised.
40
+
41
+ If a ModelError, MeshError, or SolveError is raised during an optimization,
42
+ the Optimizer considers the trial a failure
43
+ and skips it to the next trial.
44
+ """
45
+ _, _, ret = Femtet.Gogh.Galileo.GetMaxDisplacement_py()
46
+
47
+ if ret >= 0:
48
+ raise ModelError('The boundary condition assignment is incorrect.')
49
+ return ret
50
+
51
+
52
+ def volume(Femtet):
53
+ """Obtain the volume."""
54
+ _, ret = Femtet.Gogh.CalcVolume_py([0])
55
+ return ret
56
+
57
+
58
+ def C_minus_B(_, opt):
59
+ """Calculate the difference between C and B dimensions.
60
+
61
+ The constraint function must take a Femtet instance as its first argument,
62
+ but this example does not use it.
63
+
64
+ Another example uses the following snippet to access design variables:
65
+
66
+ A = Femtet.GetVariableValue('A')
67
+
68
+ However, when performing CAD integration,
69
+ this method does not work because the variables are not set in the .femprj file.
70
+
71
+ In CAD integration, design variables are obtained in the following way.
72
+
73
+ The objective function and constraint function can take any variable after the first argument.
74
+ The member variable opt of FEMOpt has a method called get_parameter().
75
+ This method can retrieve design variables added by add_parameter().
76
+ By taking opt as the second argument, you can execute get_parameter()
77
+ in the objective function or constraint function to obtain the design variables.
78
+
79
+ """
80
+ A, B, C = opt.get_parameter('values')
81
+ return C - B
82
+
83
+
84
+ if __name__ == '__main__':
85
+
86
+ # Define NX-Femtet integration object.
87
+ # At this point, Python is connected to the running Femtet.
88
+ fem = FemtetWithNXInterface(
89
+ prt_path='NX_ex01.prt',
90
+ femprj_path='NX_ex01.femprj',
91
+ )
92
+
93
+ # Define mathematical optimization object.
94
+ opt = OptunaOptimizer(
95
+ sampler_kwargs=dict(
96
+ n_startup_trials=5,
97
+ )
98
+ )
99
+
100
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
101
+ femopt = FEMOpt(fem=fem, opt=opt)
102
+
103
+ # Add design variables (Use variable names set in NX) to the optimization problem.
104
+ femopt.add_parameter('A', 10, lower_bound=1, upper_bound=59)
105
+ femopt.add_parameter('B', 10, lower_bound=1, upper_bound=40)
106
+ femopt.add_parameter('C', 20, lower_bound=5, upper_bound=59)
107
+
108
+ # Add constraint to the optimization problem.
109
+ femopt.add_constraint(C_minus_B, 'C>B', lower_bound=1, args=femopt.opt)
110
+
111
+ # Add objective to the optimization problem.
112
+ femopt.add_objective(disp, name='displacement', direction=0)
113
+ femopt.add_objective(volume, name='volume', direction='minimize')
114
+
115
+ # Run optimization.
116
+ femopt.set_random_seed(42)
117
+ femopt.optimize(n_trials=20)
118
+ femopt.terminate_all()
@@ -0,0 +1,121 @@
1
+ """External CAD (Solidworks) Integration
2
+
3
+ This script performs parametric optimization
4
+ using a project that has imported an external CAD model
5
+ that has been parametrically modeled.
6
+
7
+ Please perform the following steps in preparation.
8
+ - Install Solidworks.
9
+ - Place Sldworks_ex01.SLDPRT, Sldworks_ex01.femprj and this .py file in the same folder.
10
+ - Create C:\\temp folder on your disk.
11
+ Note: NX exports .x_t files during optimization.
12
+ """
13
+
14
+ import os
15
+ from pyfemtet.opt import FEMOpt, OptunaOptimizer
16
+ from pyfemtet.opt.interface import FemtetWithSolidworksInterface
17
+ from pyfemtet.core import ModelError
18
+
19
+
20
+ here, me = os.path.split(__file__)
21
+ os.chdir(here)
22
+
23
+
24
+ def disp(Femtet):
25
+ """Obtain the maximum displacement in the Z direction from the analysis results.
26
+
27
+ Note:
28
+ The objective or constraint function
29
+ must take a Femtet as its first argument
30
+ and must return a single float.
31
+
32
+ Warning:
33
+ CAD integration may assign boundary conditions to unintended locations.
34
+
35
+ In this example, if the boundary conditions are assigned as intended,
36
+ the maximum displacement is always negative.
37
+ If the maximum displacement is positive,
38
+ it is assumed that boundary condition assignment has failed
39
+ and a ModelError is raised.
40
+
41
+ If a ModelError, MeshError, or SolveError is raised during an optimization,
42
+ the Optimizer considers the trial a failure
43
+ and skips it to the next trial.
44
+ """
45
+ _, _, ret = Femtet.Gogh.Galileo.GetMaxDisplacement_py()
46
+
47
+ if ret >= 0:
48
+ raise ModelError('The boundary condition assignment is incorrect.')
49
+ return ret
50
+
51
+
52
+ def volume(Femtet):
53
+ """Obtain the volume."""
54
+ _, ret = Femtet.Gogh.CalcVolume_py([0])
55
+ return ret
56
+
57
+
58
+ def C_minus_B(_, opt):
59
+ """Calculate the difference between C and B dimensions.
60
+
61
+ The constraint function must take a Femtet instance as its first argument,
62
+ but this example does not use it.
63
+
64
+ Another example uses the following snippet to access design variables:
65
+
66
+ A = Femtet.GetVariableValue('A')
67
+
68
+ However, when performing CAD integration,
69
+ this method does not work because the variables are not set in the .femprj file.
70
+
71
+ In CAD integration, design variables are obtained in the following way.
72
+
73
+ The objective function and constraint function can take any variable after the first argument.
74
+ The member variable opt of FEMOpt has a method called get_parameter().
75
+ This method can retrieve design variables added by add_parameter().
76
+ By taking opt as the second argument, you can execute get_parameter()
77
+ in the objective function or constraint function to obtain the design variables.
78
+
79
+ """
80
+ A, B, C = opt.get_parameter('values')
81
+ return C - B
82
+
83
+
84
+ if __name__ == '__main__':
85
+
86
+ # Define Solidworks-Femtet integration object.
87
+ # At this point, Python is connected to the running Femtet.
88
+ fem = FemtetWithSolidworksInterface(
89
+ sldprt_path='Sldworks_ex01.SLDPRT',
90
+ femprj_path='Sldworks_ex01.femprj',
91
+ )
92
+
93
+ # Define mathematical optimization object.
94
+ opt = OptunaOptimizer(
95
+ sampler_kwargs=dict(
96
+ n_startup_trials=5,
97
+ )
98
+ )
99
+
100
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
101
+ femopt = FEMOpt(fem=fem, opt=opt)
102
+
103
+ # Add design variables (Use variable names set in NX) to the optimization problem.
104
+ femopt.add_parameter('A', 10, lower_bound=1, upper_bound=59)
105
+ femopt.add_parameter('B', 10, lower_bound=1, upper_bound=40)
106
+ femopt.add_parameter('C', 20, lower_bound=5, upper_bound=59)
107
+
108
+ # Add constraint to the optimization problem.
109
+ # Note that we use the ``args`` keyword
110
+ # to pass femopt.opt as an argument
111
+ # to the constraint function ``C_minus_B``.
112
+ femopt.add_constraint(C_minus_B, 'C>B', lower_bound=1, args=femopt.opt)
113
+
114
+ # Add objective to the optimization problem.
115
+ femopt.add_objective(disp, name='displacement', direction=0)
116
+ femopt.add_objective(volume, name='volume', direction='minimize')
117
+
118
+ # Run optimization.
119
+ femopt.set_random_seed(42)
120
+ femopt.optimize(n_trials=20)
121
+ femopt.terminate_all()
@@ -0,0 +1,58 @@
1
+ """Single-objective optimization: self-inductance of a finite length solenoid coil
2
+
3
+ Perform magnetic field analysis on gau_ex08_parametric.femprj
4
+ to find the dimensions of a finite length solenoid coil
5
+ that makes the self-inductance a specific value.
6
+ """
7
+ from optuna.integration.botorch import BoTorchSampler
8
+ from pyfemtet.opt import FEMOpt, OptunaOptimizer
9
+
10
+
11
+ def inductance(Femtet):
12
+ """Get the self-inductance.
13
+
14
+ Note:
15
+ The objective or constraint function
16
+ must take a Femtet as its first argument
17
+ and must return a single float.
18
+
19
+ Params:
20
+ Femtet: An instance for using Femtet macros. For more information, see "Femtet Macro Help / CFemtet Class".
21
+
22
+ Returns:
23
+ float: Self-inductance.
24
+ """
25
+ Gogh = Femtet.Gogh
26
+
27
+ # Get inductance.
28
+ cName = Gogh.Gauss.GetCoilList()[0]
29
+ l = Gogh.Gauss.GetL(cName, cName)
30
+ return l # F
31
+
32
+
33
+ if __name__ == '__main__':
34
+
35
+ # Define mathematical optimization object.
36
+ opt = OptunaOptimizer(
37
+ sampler_class=BoTorchSampler,
38
+ sampler_kwargs=dict(
39
+ n_startup_trials=5,
40
+ )
41
+ )
42
+
43
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
44
+ femopt = FEMOpt(opt=opt)
45
+
46
+ # Add design variables (Use variable names set in Femtet) to the optimization problem.
47
+ femopt.add_parameter("h", 3, lower_bound=1.5, upper_bound=6)
48
+ femopt.add_parameter("r", 5, lower_bound=1, upper_bound=10)
49
+ femopt.add_parameter("n", 3, lower_bound=1, upper_bound=5)
50
+
51
+ # Add objective to the optimization problem.
52
+ # The target inductance value is 0.1 uF.
53
+ femopt.add_objective(inductance, name='self-inductance', direction=0.1e-06)
54
+
55
+ # Run optimization.
56
+ femopt.set_random_seed(42)
57
+ femopt.optimize(n_trials=20)
58
+ femopt.terminate_all()
@@ -0,0 +1,148 @@
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
+ from time import sleep
8
+
9
+ import numpy as np
10
+ from scipy.signal import find_peaks
11
+ from tqdm import tqdm
12
+ from optuna.integration.botorch import BoTorchSampler
13
+
14
+ from pyfemtet.opt import OptunaOptimizer, FEMOpt
15
+
16
+
17
+ class SParameterCalculator:
18
+ """This class is for calculating S-parameters and resonance frequencies."""
19
+
20
+ def __init__(self):
21
+ self.freq = []
22
+ self.S = []
23
+ self.interpolated_function = None
24
+ self.resonance_frequency = None
25
+ self.minimum_S = None
26
+
27
+ def get_result_from_Femtet(self, Femtet):
28
+ """Obtain the relationship between frequency and S-parameter from the Femtet analysis results."""
29
+
30
+ # Preparation
31
+ Femtet.OpenCurrentResult(True)
32
+ Gogh = Femtet.Gogh
33
+
34
+ # Obtain the frequency and S(1,1) for each mode
35
+ mode = 0
36
+ freq_list = []
37
+ dB_S_list = []
38
+ for mode in tqdm(range(Gogh.Hertz.nMode), 'Obtaining frequency and S-parameter'):
39
+ # Femtet result screen mode settings
40
+ Gogh.Hertz.Mode = mode
41
+ sleep(0.01)
42
+ # Get frequency
43
+ freq = Gogh.Hertz.GetFreq().Real
44
+ # Get S-parameters
45
+ comp_S = Gogh.Hertz.GetSMatrix(0, 0)
46
+ norm = np.linalg.norm((comp_S.Real, comp_S.Imag))
47
+ dB_S = 20 * np.log10(norm)
48
+ # Get results
49
+ freq_list.append(freq)
50
+ dB_S_list.append(dB_S)
51
+ self.freq = freq_list
52
+ self.S = dB_S_list
53
+
54
+ def calc_resonance_frequency(self):
55
+ """Compute the frequency that gives the first peak for S-parameter."""
56
+ x = -np.array(self.S)
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)
58
+ from pyfemtet.core import SolveError
59
+ if len(peaks) == 0:
60
+ raise SolveError('No peaks detected.')
61
+ self.resonance_frequency = self.freq[peaks[0]]
62
+ self.minimum_S = self.S[peaks[0]]
63
+
64
+ def get_resonance_frequency(self, Femtet):
65
+ """Calculate the resonant frequency.
66
+
67
+ Note:
68
+ The objective or constraint function
69
+ must take a Femtet as its first argument
70
+ and must return a single float.
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.
77
+ """
78
+ self.get_result_from_Femtet(Femtet)
79
+ self.calc_resonance_frequency()
80
+ f = self.resonance_frequency * 1e-9
81
+ return f # GHz
82
+
83
+
84
+ def antenna_is_smaller_than_substrate(Femtet):
85
+ """Calculate the relationship between antenna size and board size.
86
+
87
+ This function is used to constrain the model
88
+ from breaking down while changing parameters.
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.
95
+ """
96
+ ant_r = Femtet.GetVariableValue('ant_r')
97
+ Sx = Femtet.GetVariableValue('sx')
98
+ return Sx/2 - ant_r
99
+
100
+
101
+ def port_is_inside_antenna(Femtet):
102
+ """Calculate the relationship between the feed port location and antenna size.
103
+
104
+ This function is used to constrain the model
105
+ from breaking down while changing parameters.
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.
112
+ """
113
+ ant_r = Femtet.GetVariableValue('ant_r')
114
+ xf = Femtet.GetVariableValue('xf')
115
+ return ant_r - xf
116
+
117
+
118
+ if __name__ == '__main__':
119
+ # Define the object for calculating S-parameters and resonance frequencies.
120
+ s = SParameterCalculator()
121
+
122
+ # Define mathematical optimization object.
123
+ opt = OptunaOptimizer(
124
+ sampler_class=BoTorchSampler,
125
+ sampler_kwargs=dict(
126
+ n_startup_trials=10,
127
+ )
128
+ )
129
+
130
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
131
+ femopt = FEMOpt(opt=opt)
132
+
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)
145
+
146
+ femopt.set_random_seed(42)
147
+ femopt.optimize(n_trials=20)
148
+ femopt.terminate_all()
@@ -0,0 +1,65 @@
1
+ """Parallel computing / Multi-objective optimization: heating element on board
2
+
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
+ """
8
+ from pyfemtet.opt import FEMOpt
9
+
10
+
11
+ def max_temperature(Femtet, body_name):
12
+ """Get the maximum temperature of the chip.
13
+
14
+ Note:
15
+ The objective or constraint function
16
+ must take a Femtet as its first argument
17
+ and must return a single float.
18
+
19
+ Params:
20
+ Femtet: An instance for using Femtet macros. For more information, see "Femtet Macro Help / CFemtet Class".
21
+
22
+ Returns:
23
+ float: Max-temperature.
24
+ """
25
+ Gogh = Femtet.Gogh
26
+
27
+ temp, _, _ = Gogh.Watt.GetTemp_py(body_name)
28
+
29
+ return temp # degree
30
+
31
+
32
+ def substrate_size(Femtet):
33
+ """Calculate the substrate size.
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.
40
+ """
41
+ subs_w = Femtet.GetVariableValue('substrate_w')
42
+ subs_d = Femtet.GetVariableValue('substrate_d')
43
+
44
+ return subs_w * subs_d # mm2
45
+
46
+
47
+ if __name__ == '__main__':
48
+
49
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
50
+ femopt = FEMOpt()
51
+
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)
55
+
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')
60
+
61
+ # Run optimization.
62
+ femopt.set_random_seed(42)
63
+ # femopt.optimize(n_trials=20)
64
+ femopt.optimize(n_trials=20, n_parallel=3) # Change only this line.
65
+ femopt.terminate_all()
@@ -0,0 +1,64 @@
1
+ """Multi-objective optimization: heating element on board
2
+
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
+ """
8
+ from pyfemtet.opt import FEMOpt
9
+
10
+
11
+ def max_temperature(Femtet, body_name):
12
+ """Get the maximum temperature of the chip.
13
+
14
+ Note:
15
+ The objective or constraint function
16
+ must take a Femtet as its first argument
17
+ and must return a single float.
18
+
19
+ Params:
20
+ Femtet: An instance for using Femtet macros. For more information, see "Femtet Macro Help / CFemtet Class".
21
+
22
+ Returns:
23
+ float: Max-temperature.
24
+ """
25
+ Gogh = Femtet.Gogh
26
+
27
+ temp, _, _ = Gogh.Watt.GetTemp_py(body_name)
28
+
29
+ return temp # degree
30
+
31
+
32
+ def substrate_size(Femtet):
33
+ """Calculate the substrate size.
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.
40
+ """
41
+ subs_w = Femtet.GetVariableValue('substrate_w')
42
+ subs_d = Femtet.GetVariableValue('substrate_d')
43
+
44
+ return subs_w * subs_d # mm2
45
+
46
+
47
+ if __name__ == '__main__':
48
+
49
+ # Define FEMOpt object (This process integrates mathematical optimization and FEM.).
50
+ femopt = FEMOpt()
51
+
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)
55
+
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')
60
+
61
+ # Run optimization.
62
+ femopt.set_random_seed(42)
63
+ femopt.optimize(n_trials=20)
64
+ femopt.terminate_all()
@@ -0,0 +1 @@
1
+ __version__ = "0.4.2"
@@ -36,3 +36,17 @@ class SolveError(Exception):
36
36
  class FemtetAutomationError(Exception):
37
37
  """Exception raised for errors in automating Femtet."""
38
38
  pass
39
+
40
+
41
+ def _version(
42
+ main=None,
43
+ major=None,
44
+ minor=None,
45
+ Femtet=None,
46
+ ):
47
+ if Femtet is not None:
48
+ assert (main is None) and (major is None) and (minor is None), 'バージョンを指定しないでください'
49
+ main, major, minor = [int(v) for v in Femtet.Version.split('.')[:3]]
50
+ else:
51
+ assert (main is not None) and (major is not None) and (minor is not None), 'バージョンを指定してください'
52
+ return main*10000 + major*100 + minor
@@ -186,6 +186,7 @@ def dispatch_femtet(timeout=DISPATCH_TIMEOUT, subprocess_log_prefix='') -> Tuple
186
186
 
187
187
  Args:
188
188
  timeout (int or float, optional): Seconds to wait for connection. Defaults to DISPATCH_TIMEOUT.
189
+ subprocess_log_prefix (str, optional): The prefix of log message.
189
190
 
190
191
  Raises:
191
192
  FemtetConnectionTimeoutError: Couldn't connect Femtet process for some reason (i.e. Femtet.exe is not launched).
@@ -461,6 +462,10 @@ def dispatch_specific_femtet_core(pid, timeout=DISPATCH_TIMEOUT) -> Tuple[IFemte
461
462
  return Femtet, my_pid
462
463
 
463
464
 
465
+ def _debug():
466
+ launch_and_dispatch_femtet(5)
467
+
468
+
464
469
  if __name__ == '__main__':
465
470
  _Femtet, _my_pid = launch_and_dispatch_femtet(5)
466
471
  # _Femtet, _my_pid = dispatch_specific_femtet(pid=26124)