pyfemtet 0.5.0__py3-none-any.whl → 0.5.2__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 +12 -3
- pyfemtet/opt/_femopt_core.py +73 -23
- pyfemtet/opt/optimizer/_optuna.py +1 -1
- pyfemtet/opt/optimizer/_optuna_botorchsampler_parameter_constraint_helper.py +14 -10
- pyfemtet/opt/samples/femprj_sample/constrained_pipe.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/constrained_pipe.py +97 -0
- pyfemtet/opt/samples/femprj_sample/constrained_pipe_test_result.reccsv +13 -0
- pyfemtet/opt/samples/femprj_sample_jp/constrained_pipe_jp.py +93 -0
- {pyfemtet-0.5.0.dist-info → pyfemtet-0.5.2.dist-info}/METADATA +3 -3
- {pyfemtet-0.5.0.dist-info → pyfemtet-0.5.2.dist-info}/RECORD +14 -11
- pyfemtet/opt/samples/femprj_sample/ParametricIF - True.femprj +0 -0
- {pyfemtet-0.5.0.dist-info → pyfemtet-0.5.2.dist-info}/LICENSE +0 -0
- {pyfemtet-0.5.0.dist-info → pyfemtet-0.5.2.dist-info}/WHEEL +0 -0
- {pyfemtet-0.5.0.dist-info → pyfemtet-0.5.2.dist-info}/entry_points.txt +0 -0
pyfemtet/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.5.
|
|
1
|
+
__version__ = "0.5.2"
|
pyfemtet/opt/_femopt.py
CHANGED
|
@@ -12,7 +12,7 @@ from traceback import print_exception
|
|
|
12
12
|
# 3rd-party
|
|
13
13
|
import numpy as np
|
|
14
14
|
import pandas as pd
|
|
15
|
-
from dask.distributed import LocalCluster, Client
|
|
15
|
+
from dask.distributed import LocalCluster, Client, Worker
|
|
16
16
|
|
|
17
17
|
# pyfemtet relative
|
|
18
18
|
from pyfemtet.opt.interface import FEMInterface, FemtetInterface
|
|
@@ -452,10 +452,16 @@ class FEMOpt:
|
|
|
452
452
|
else:
|
|
453
453
|
# ローカルクラスターを構築
|
|
454
454
|
logger.info('Launching single machine cluster. This may take tens of seconds.')
|
|
455
|
-
cluster = LocalCluster(
|
|
456
|
-
|
|
455
|
+
cluster = LocalCluster(
|
|
456
|
+
processes=True,
|
|
457
|
+
n_workers=n_parallel, # n_parallel = n_parallel - 1 + 1; main 分減らし、monitor 分増やす
|
|
458
|
+
threads_per_worker=1,
|
|
459
|
+
worker_class=Worker,
|
|
460
|
+
)
|
|
461
|
+
logger.info('LocalCluster launched successfully.')
|
|
457
462
|
self.client = Client(cluster, direct_to_workers=False)
|
|
458
463
|
self.scheduler_address = self.client.scheduler.address
|
|
464
|
+
logger.info('Client launched successfully.')
|
|
459
465
|
|
|
460
466
|
# 最適化タスクを振り分ける worker を指定
|
|
461
467
|
subprocess_indices = list(range(n_parallel))[1:]
|
|
@@ -487,6 +493,7 @@ class FEMOpt:
|
|
|
487
493
|
indexes,
|
|
488
494
|
directions,
|
|
489
495
|
)
|
|
496
|
+
logger.info('Femtet loaded successfully.')
|
|
490
497
|
|
|
491
498
|
# actor の設定
|
|
492
499
|
self.status = OptimizationStatus(_client)
|
|
@@ -500,6 +507,7 @@ class FEMOpt:
|
|
|
500
507
|
_client,
|
|
501
508
|
metadata,
|
|
502
509
|
)
|
|
510
|
+
logger.info('Status Actor initialized successfully.')
|
|
503
511
|
|
|
504
512
|
# launch monitor
|
|
505
513
|
self.monitor_process_future = _client.submit(
|
|
@@ -516,6 +524,7 @@ class FEMOpt:
|
|
|
516
524
|
workers=self.monitor_process_worker_name,
|
|
517
525
|
allow_other_workers=False
|
|
518
526
|
)
|
|
527
|
+
logger.info('Process monitor initialized successfully.')
|
|
519
528
|
|
|
520
529
|
# fem
|
|
521
530
|
self.fem._setup_before_parallel(_client)
|
pyfemtet/opt/_femopt_core.py
CHANGED
|
@@ -150,9 +150,7 @@ def _remove_indent(source: str, indent: int) -> str: # returns source
|
|
|
150
150
|
return edited_source
|
|
151
151
|
|
|
152
152
|
|
|
153
|
-
def
|
|
154
|
-
if target is None:
|
|
155
|
-
target = ''
|
|
153
|
+
def _check_access_femtet_objects(fun, target: str = 'Femtet'):
|
|
156
154
|
|
|
157
155
|
# 関数fのソースコードを取得
|
|
158
156
|
source = inspect.getsource(fun)
|
|
@@ -162,36 +160,88 @@ def _check_accsess_femtet_objects(fun, target: str = None):
|
|
|
162
160
|
# instanceメソッドなどの場合を想定してインデントを削除
|
|
163
161
|
source = _remove_indent(source, _get_scope_indent(source))
|
|
164
162
|
tree = ast.parse(source)
|
|
165
|
-
|
|
163
|
+
|
|
164
|
+
except Exception:
|
|
166
165
|
return False # パースに失敗するからと言ってエラーにするまででもない
|
|
167
166
|
|
|
168
|
-
#
|
|
167
|
+
# if function or staticmethod, 1st argument is Femtet. Find the name.
|
|
168
|
+
varname_contains_femtet = '' # invalid variable name
|
|
169
169
|
for node in ast.walk(tree):
|
|
170
170
|
if isinstance(node, ast.FunctionDef):
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
#
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
171
|
+
all_arguments: ast.arguments = node.args
|
|
172
|
+
|
|
173
|
+
args: list[ast.arg] = all_arguments.args
|
|
174
|
+
# args.extend(all_arguments.posonlyargs) # 先にこっちを入れるべきかも
|
|
175
|
+
|
|
176
|
+
target_arg = args[0]
|
|
177
|
+
|
|
178
|
+
# if class method or instance method, 2nd argument is it.
|
|
179
|
+
# In this implementation, we cannot detect the FunctionDef is
|
|
180
|
+
# method or not because the part of source code is unindented and parsed.
|
|
181
|
+
if target_arg.arg == 'self' or target_arg.arg == 'cls':
|
|
182
|
+
if len(args) > 1:
|
|
183
|
+
target_arg = args[1]
|
|
184
|
+
else:
|
|
185
|
+
target_arg = None
|
|
186
|
+
|
|
187
|
+
if target_arg is not None:
|
|
188
|
+
varname_contains_femtet = target_arg.arg
|
|
189
|
+
|
|
190
|
+
# check Femtet access
|
|
191
|
+
if target == 'Femtet':
|
|
192
|
+
for node in ast.walk(tree):
|
|
193
|
+
|
|
194
|
+
# by accessing argument directory
|
|
195
|
+
if isinstance(node, ast.Name):
|
|
196
|
+
# found local variables
|
|
197
|
+
node: ast.Name
|
|
198
|
+
if node.id == varname_contains_femtet:
|
|
199
|
+
# found Femtet
|
|
200
|
+
return True
|
|
201
|
+
|
|
202
|
+
# by accessing inside method
|
|
203
|
+
elif isinstance(node, ast.Attribute):
|
|
204
|
+
# found attribute of something
|
|
205
|
+
node: ast.Attribute
|
|
206
|
+
if node.attr == 'Femtet':
|
|
207
|
+
# found **.Femtet.**
|
|
208
|
+
return True
|
|
209
|
+
|
|
210
|
+
# check Gogh access
|
|
211
|
+
elif target == 'Gogh':
|
|
212
|
+
for node in ast.walk(tree):
|
|
213
|
+
if isinstance(node, ast.Attribute):
|
|
214
|
+
if node.attr == 'Gogh':
|
|
215
|
+
# found **.Gogh.**
|
|
216
|
+
node: ast.Attribute
|
|
217
|
+
parent = node.value
|
|
218
|
+
|
|
219
|
+
# by accessing argument directory
|
|
220
|
+
if isinstance(parent, ast.Name):
|
|
221
|
+
# found *.Gogh.**
|
|
222
|
+
parent: ast.Name
|
|
223
|
+
if parent.id == varname_contains_femtet:
|
|
224
|
+
# found Femtet.Gogh.**
|
|
225
|
+
return True
|
|
226
|
+
|
|
227
|
+
# by accessing inside method
|
|
228
|
+
if isinstance(parent, ast.Attribute):
|
|
229
|
+
# found **.*.Gogh.**
|
|
230
|
+
parent: ast.Attribute
|
|
231
|
+
if parent.attr == 'Femtet':
|
|
232
|
+
# found **.Femtet.Gogh.**
|
|
233
|
+
return True
|
|
234
|
+
|
|
235
|
+
# ここまで来たならば target へのアクセスはおそらくない
|
|
236
|
+
return False
|
|
187
237
|
|
|
188
238
|
|
|
189
239
|
def _is_access_gogh(fun):
|
|
190
|
-
return
|
|
240
|
+
return _check_access_femtet_objects(fun, target='Gogh')
|
|
191
241
|
|
|
192
242
|
|
|
193
243
|
def _is_access_femtet(fun):
|
|
194
|
-
return
|
|
244
|
+
return _check_access_femtet_objects(fun, target='Femtet')
|
|
195
245
|
|
|
196
246
|
|
|
197
247
|
def is_feasible(value, lb, ub):
|
|
@@ -39,12 +39,22 @@ def do_patch(
|
|
|
39
39
|
opt (OptunaOptimizer): OptunaOptimizer.
|
|
40
40
|
"""
|
|
41
41
|
import optuna_integration
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
from optuna_integration import version
|
|
44
|
+
if int(version.__version__.split('.')[0]) >= 4:
|
|
45
|
+
target_fun = optuna_integration.botorch.botorch.optimize_acqf
|
|
46
|
+
else:
|
|
47
|
+
target_fun = optuna_integration.botorch.optimize_acqf
|
|
48
|
+
|
|
43
49
|
new_fun: callable = OptimizeReplacedACQF(target_fun)
|
|
44
50
|
new_fun.set_constraints(list(constraints.values()))
|
|
45
51
|
new_fun.set_study(study)
|
|
46
52
|
new_fun.set_opt(opt)
|
|
47
|
-
|
|
53
|
+
|
|
54
|
+
if int(version.__version__.split('.')[0]) >= 4:
|
|
55
|
+
optuna_integration.botorch.botorch.optimize_acqf = new_fun
|
|
56
|
+
else:
|
|
57
|
+
optuna_integration.botorch.optimize_acqf = new_fun
|
|
48
58
|
|
|
49
59
|
|
|
50
60
|
class GeneralFunctionWithForwardDifference(torch.autograd.Function):
|
|
@@ -135,14 +145,8 @@ def evaluate_pyfemtet_cns(study: Study, cns: Constraint, norm_x: np.ndarray, opt
|
|
|
135
145
|
bool: feasible or not.
|
|
136
146
|
"""
|
|
137
147
|
# ===== unnormalize x =====
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if len(trial.distributions) > 0:
|
|
141
|
-
break
|
|
142
|
-
else:
|
|
143
|
-
raise RuntimeError('Cannot detect bounds because of no COMPLETE trials. Certify 1 or more sampling excluding initial conditions.')
|
|
144
|
-
search_space = study.sampler.infer_relative_search_space(study, trial)
|
|
145
|
-
trans = _SearchSpaceTransform(trial.distributions, transform_0_1=True, transform_log=False, transform_step=False)
|
|
148
|
+
search_space = study.sampler.infer_relative_search_space(study, None)
|
|
149
|
+
trans = _SearchSpaceTransform(search_space, transform_0_1=True, transform_log=False, transform_step=False)
|
|
146
150
|
params = trans.untransform(norm_x)
|
|
147
151
|
|
|
148
152
|
# ===== update OptunaOptimizer and FEMInterface who is referenced by cns =====
|
|
Binary file
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""A sample to implement constrained optimization.
|
|
2
|
+
|
|
3
|
+
This section describes the types of constraints and
|
|
4
|
+
the steps to run optimization on models that require them.
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from optuna_integration import BoTorchSampler
|
|
9
|
+
from pyfemtet.opt import FEMOpt, OptunaOptimizer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def mises_stress(Femtet):
|
|
13
|
+
"""Calculate the von Mises stress as the objective function.
|
|
14
|
+
|
|
15
|
+
This function is called automatically by the FEMOpt
|
|
16
|
+
object while the optimization is running.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
Femtet: When defining an objective or constraint
|
|
20
|
+
function using PyFemtet, the first argument
|
|
21
|
+
must take a Femtet instance.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
float: A single float representing the expression value you want to constrain.
|
|
25
|
+
"""
|
|
26
|
+
return Femtet.Gogh.Galileo.GetMaxStress_py()[2]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def radius_diff(Femtet, opt):
|
|
30
|
+
"""Calculate the difference between the outer and inner radii of the pipe.
|
|
31
|
+
|
|
32
|
+
This constraint is called to ensure that the
|
|
33
|
+
inner radius of the pipe does not exceed the
|
|
34
|
+
outer radius while the optimization is running.
|
|
35
|
+
|
|
36
|
+
Note:
|
|
37
|
+
If you are using BoTorchSampler of OptunaOptimizer
|
|
38
|
+
and use strict constraints, be aware that accessing
|
|
39
|
+
the Femtet can be very slow, as it requires repeated
|
|
40
|
+
calculations to propose parameters.
|
|
41
|
+
We recommend that you do not access the Femtet,
|
|
42
|
+
but rather get the parameters and perform the
|
|
43
|
+
calculations via the Optimizer object, as in this
|
|
44
|
+
function example.
|
|
45
|
+
|
|
46
|
+
NOT recommended::
|
|
47
|
+
|
|
48
|
+
p = Femtet.GetVariableValue('p')
|
|
49
|
+
|
|
50
|
+
instead, use optimizer::
|
|
51
|
+
|
|
52
|
+
params = opt.get_parameter()
|
|
53
|
+
p = params['p']
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
Femtet: When defining an objective or constraint
|
|
57
|
+
function using PyFemtet, the first argument
|
|
58
|
+
must take a Femtet instance.
|
|
59
|
+
opt: This object allows you to obtain the outer
|
|
60
|
+
radius and inner radius values without going
|
|
61
|
+
through Femtet.
|
|
62
|
+
"""
|
|
63
|
+
params = opt.get_parameter()
|
|
64
|
+
internal_r = params['internal_r']
|
|
65
|
+
external_r = params['external_r']
|
|
66
|
+
return external_r - internal_r
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
if __name__ == '__main__':
|
|
70
|
+
# Setup optimization method
|
|
71
|
+
opt = OptunaOptimizer(
|
|
72
|
+
sampler_class=BoTorchSampler,
|
|
73
|
+
sampler_kwargs=dict(
|
|
74
|
+
n_startup_trials=3, # The first three samples are randomly sampled.
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
femopt = FEMOpt(opt=opt)
|
|
78
|
+
|
|
79
|
+
# Add parameters
|
|
80
|
+
femopt.add_parameter("external_r", 10, lower_bound=0.1, upper_bound=10)
|
|
81
|
+
femopt.add_parameter("internal_r", 5, lower_bound=0.1, upper_bound=10)
|
|
82
|
+
|
|
83
|
+
# Add the strict constraint not to exceed the
|
|
84
|
+
# outer radius while the optimization is running.
|
|
85
|
+
femopt.add_constraint(
|
|
86
|
+
radius_diff, # Constraint function (returns external radius - internal radius).
|
|
87
|
+
name='wall thickness', # You can name the function anything you want.
|
|
88
|
+
lower_bound=1, # Lower bound of constraint function (set minimum wall thickness is 1).
|
|
89
|
+
args=(femopt.opt,) # Additional arguments passed to the function.
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Add the objective
|
|
93
|
+
femopt.add_objective(mises_stress, name='Mises Stress')
|
|
94
|
+
|
|
95
|
+
# Run optimization.
|
|
96
|
+
femopt.set_random_seed(42)
|
|
97
|
+
femopt.optimize(n_trials=10)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"",prm,prm_lb,prm_ub,prm,prm_lb,prm_ub,obj,obj_direction,,cns,cns_lb,cns_ub,,,,
|
|
2
|
+
,,,,,,,,,,,,,,,,
|
|
3
|
+
trial,external_r,external_r_lower_bound,external_r_upper_bound,internal_r,internal_r_lower_bound,internal_r_upper_bound,Mises Stress,Mises Stress_direction,non_domi,wall thickness,wall thickness_lower_bound,wall thickness_upper_bound,feasible,hypervolume,message,time
|
|
4
|
+
1,10.0,0.1,10.0,5.0,0.1,10.0,2369132.9299968677,minimize,False,5.0,1,,True,-1.0,initial,2024-09-17 14:52:32.436730
|
|
5
|
+
2,7.34674002393291,0.1,10.0,6.026718993550662,0.1,10.0,5797829.750527166,minimize,False,1.3200210303822484,1,,True,-1.0,,2024-09-17 14:52:42.927138
|
|
6
|
+
3,8.341182143924176,0.1,10.0,2.202157195714934,0.1,10.0,1977631.590419345,minimize,False,6.139024948209242,1,,True,-1.0,,2024-09-17 14:52:54.382893
|
|
7
|
+
4,9.999999999999995,0.1,10.0,0.6764719819158711,0.1,10.0,1514026.80705058,minimize,False,9.323528018084124,1,,True,-1.0,,2024-09-17 14:53:32.128331
|
|
8
|
+
5,7.61174007452904,0.1,10.0,0.10000000000001566,0.1,10.0,398224.5447358758,minimize,True,7.511740074529024,1,,True,-1.0,,2024-09-17 14:54:08.541865
|
|
9
|
+
6,5.026961232239628,0.1,10.0,0.10000000000001101,0.1,10.0,485322.32959281537,minimize,False,4.926961232239617,1,,True,-1.0,,2024-09-17 14:54:39.695340
|
|
10
|
+
7,1.1000000916874046,0.1,10.0,0.1,0.1,10.0,613872.6231008903,minimize,False,1.0000000916874046,1,,True,-1.0,,2024-09-17 14:55:07.711879
|
|
11
|
+
8,3.122874622702614,0.1,10.0,0.1,0.1,10.0,497544.0108231131,minimize,False,3.0228746227026138,1,,True,-1.0,,2024-09-17 14:55:41.036763
|
|
12
|
+
9,9.999999999999998,0.1,10.0,3.7062659141309533,0.1,10.0,2092780.7380693094,minimize,False,6.293734085869045,1,,True,-1.0,,2024-09-17 14:56:28.269065
|
|
13
|
+
10,6.601571760977393,0.1,10.0,0.10000000004171199,0.1,10.0,456263.04356135987,minimize,False,6.501571760935681,1,,True,-1.0,,2024-09-17 14:57:04.427906
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""拘束付き最適化を実装するサンプル。
|
|
2
|
+
|
|
3
|
+
このセクションでは、拘束の種類と、拘束を必要とするモデルで
|
|
4
|
+
最適化を実行する手順について説明します。
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from optuna_integration import BoTorchSampler
|
|
9
|
+
from pyfemtet.opt import FEMOpt, OptunaOptimizer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def mises_stress(Femtet):
|
|
13
|
+
"""フォンミーゼス応力を目的関数として計算します。
|
|
14
|
+
|
|
15
|
+
この関数は、最適化の実行中に FEMOpt オブジェクトによって
|
|
16
|
+
自動的に呼び出されます。
|
|
17
|
+
|
|
18
|
+
引数:
|
|
19
|
+
Femtet: PyFemtet を使用して目的関数または拘束関数を
|
|
20
|
+
定義する場合、最初の引数は Femtet インスタンスを
|
|
21
|
+
取る必要があります。
|
|
22
|
+
|
|
23
|
+
戻り値:
|
|
24
|
+
float: 目的または拘束関数は単一の float を返すよう定義してください。
|
|
25
|
+
"""
|
|
26
|
+
return Femtet.Gogh.Galileo.GetMaxStress_py()[2]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def radius_diff(Femtet, opt):
|
|
30
|
+
"""パイプの外側の半径と内側の半径の差を計算します。
|
|
31
|
+
|
|
32
|
+
この拘束は、最適化の実行中にパイプの内側の半径が
|
|
33
|
+
外側の半径を超えないようにするために呼び出されます。
|
|
34
|
+
|
|
35
|
+
注意:
|
|
36
|
+
OptunaOptimizer の BoTorchSampler を使用していて、
|
|
37
|
+
strict な拘束を使用する場合、パラメータを提案するため
|
|
38
|
+
に繰り返し計算が必要になるため、Femtet へのアクセスが
|
|
39
|
+
非常に遅くなる可能性があることに注意してください。
|
|
40
|
+
この関数の例のように、Femtet にアクセスするのではなく、
|
|
41
|
+
Optimizer オブジェクトを介してパラメータを取得して計算
|
|
42
|
+
を実行することをお勧めします。
|
|
43
|
+
|
|
44
|
+
非推奨::
|
|
45
|
+
|
|
46
|
+
p = Femtet.GetVariableValue('p')
|
|
47
|
+
|
|
48
|
+
代わりに::
|
|
49
|
+
|
|
50
|
+
params = opt.get_parameter()
|
|
51
|
+
p = params['p']
|
|
52
|
+
|
|
53
|
+
引数:
|
|
54
|
+
Femtet: PyFemtet を使用して目的関数または拘束関数を
|
|
55
|
+
定義する場合、最初の引数は Femtet インスタンスを
|
|
56
|
+
取る必要があります。
|
|
57
|
+
opt: このオブジェクトを使用すると、Femtet を経由せず
|
|
58
|
+
に外側の半径と内側の半径の値を取得できます。
|
|
59
|
+
"""
|
|
60
|
+
params = opt.get_parameter()
|
|
61
|
+
internal_r = params['internal_r']
|
|
62
|
+
external_r = params['external_r']
|
|
63
|
+
return external_r - internal_r
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == '__main__':
|
|
67
|
+
# 最適化手法のセットアップ
|
|
68
|
+
opt = OptunaOptimizer(
|
|
69
|
+
sampler_class=BoTorchSampler,
|
|
70
|
+
sampler_kwargs=dict(
|
|
71
|
+
n_startup_trials=3, # 最初の 3 回はランダムサンプリングを行います。
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
femopt = FEMOpt(opt=opt)
|
|
75
|
+
|
|
76
|
+
# 変数の追加
|
|
77
|
+
femopt.add_parameter("external_r", 10, lower_bound=0.1, upper_bound=10)
|
|
78
|
+
femopt.add_parameter("internal_r", 5, lower_bound=0.1, upper_bound=10)
|
|
79
|
+
|
|
80
|
+
# 最適化の実行中に外側の半径を超えないように strict 拘束を追加します。
|
|
81
|
+
femopt.add_constraint(
|
|
82
|
+
radius_diff, # 拘束関数 (ここでは 外半径 - 内半径).
|
|
83
|
+
name='管厚さ', # 拘束関数にはプログラム上の名前とは別に自由な名前を付与できます.
|
|
84
|
+
lower_bound=1, # 拘束関数の下限 (ここでは管の厚みを最低 1 とする).
|
|
85
|
+
args=(femopt.opt,) # 拘束関数に渡される、Femtet 以外の追加の引数.
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# 目的関数の追加
|
|
89
|
+
femopt.add_objective(mises_stress, name='ミーゼス応力')
|
|
90
|
+
|
|
91
|
+
# 最適化の実行
|
|
92
|
+
femopt.set_random_seed(42)
|
|
93
|
+
femopt.optimize(n_trials=10)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyfemtet
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: Design parameter optimization using Femtet.
|
|
5
5
|
Home-page: https://github.com/pyfemtet/pyfemtet
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -22,8 +22,8 @@ Requires-Dist: distributed (>=2023.12.1,<2024.0.0)
|
|
|
22
22
|
Requires-Dist: femtetutils (>=1.0.0,<2.0.0)
|
|
23
23
|
Requires-Dist: numpy (>=1.26.2,<2.0.0)
|
|
24
24
|
Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
|
|
25
|
-
Requires-Dist: optuna (>=3.4.0,<
|
|
26
|
-
Requires-Dist: optuna-integration (>=3.6.0,<
|
|
25
|
+
Requires-Dist: optuna (>=3.4.0,<5.0.0)
|
|
26
|
+
Requires-Dist: optuna-integration (>=3.6.0,<5.0.0)
|
|
27
27
|
Requires-Dist: pandas (>=2.1.3,<3.0.0)
|
|
28
28
|
Requires-Dist: plotly (>=5.22.0,<6.0.0)
|
|
29
29
|
Requires-Dist: psutil (>=5.9.6,<6.0.0)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pyfemtet/__init__.py,sha256=
|
|
1
|
+
pyfemtet/__init__.py,sha256=wlmBF5A1gVspskZOpqNe0Xi1AY5ZRYF38SMV3fRd_LA,21
|
|
2
2
|
pyfemtet/core.py,sha256=3lqfBGJ5IuKz2Nqj5pRo7YQqKwx_0ZDL72u95Ur_1p0,1386
|
|
3
3
|
pyfemtet/dispatch_extensions.py,sha256=XVZajbjh7mb6NG4Hq8qff2TJWab75r4Hd59cIvCRsVg,16213
|
|
4
4
|
pyfemtet/logger.py,sha256=JYD0FvzijMS2NvZN7VT7vZA5hqtHEkvS93AHlIMDePw,2507
|
|
@@ -11,8 +11,8 @@ pyfemtet/message/locales/ja/LC_MESSAGES/messages.po,sha256=f8rimJEqmLdlrE7JBwETm
|
|
|
11
11
|
pyfemtet/message/locales/messages.pot,sha256=_gVMy6qaSU7Qu6zIY8KQizb1XpTZ0ijLKbnnk4lAAdg,13635
|
|
12
12
|
pyfemtet/message/messages.py,sha256=i0cOOV8NnBeT1gG-tqgnu_3dIym1hZG8Hzg38sh_Qeo,13187
|
|
13
13
|
pyfemtet/opt/__init__.py,sha256=MPrUWeLZLrJ-ApVckn8dsn3QmRH13aPzit5JgaoshG8,696
|
|
14
|
-
pyfemtet/opt/_femopt.py,sha256=
|
|
15
|
-
pyfemtet/opt/_femopt_core.py,sha256=
|
|
14
|
+
pyfemtet/opt/_femopt.py,sha256=_WxsnCk22UnnFPeGxVOrVDyWnuOOVUwRLvUL9xSxwuQ,26998
|
|
15
|
+
pyfemtet/opt/_femopt_core.py,sha256=jla01evKNA3sOR-BDuMM-JN5xgh1jwtRd_0JMes4_Qc,29608
|
|
16
16
|
pyfemtet/opt/_test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
pyfemtet/opt/_test_utils/control_femtet.py,sha256=Oy2MmNS-LhUXF9rKLa8AXAfJhppIQI8Nha8LmEZflmk,1169
|
|
18
18
|
pyfemtet/opt/_test_utils/hyper_sphere.py,sha256=nQhw8EIY0DwvcTqrbKhkxiITLZifr4-nG77E-_6ggmA,700
|
|
@@ -27,8 +27,8 @@ pyfemtet/opt/interface/_femtet_with_nx/update_model.py,sha256=P7VH0i_o-X9OUe6AGa
|
|
|
27
27
|
pyfemtet/opt/interface/_femtet_with_sldworks.py,sha256=Ldr8Esa5xZ-D_E5uIXBTF2DHslXVMFDYOsqTd8FhY1M,6242
|
|
28
28
|
pyfemtet/opt/optimizer/__init__.py,sha256=wdz7PXkcSJ9Z2OHoegfGvYrnj_OAyU39BvDyiy3QnVw,407
|
|
29
29
|
pyfemtet/opt/optimizer/_base.py,sha256=lKCDGoAtOLwqNaP7qfqYJ69AHxq9YZVivTP14VHYxZU,12136
|
|
30
|
-
pyfemtet/opt/optimizer/_optuna.py,sha256=
|
|
31
|
-
pyfemtet/opt/optimizer/_optuna_botorchsampler_parameter_constraint_helper.py,sha256=
|
|
30
|
+
pyfemtet/opt/optimizer/_optuna.py,sha256=MojfB0oQCjSzS-hJNiD_Wn-vPDJbsMUydMq2ht6Ww9g,11570
|
|
31
|
+
pyfemtet/opt/optimizer/_optuna_botorchsampler_parameter_constraint_helper.py,sha256=dJsQIbPeAI9N46iavTB6PDpoZ_Ol7WFVEOPN6Pdx7KM,12223
|
|
32
32
|
pyfemtet/opt/optimizer/_scipy.py,sha256=M3q25VuRazDzXUWC25z7hGbNq2Qg9158NjTSNBvi2pk,4347
|
|
33
33
|
pyfemtet/opt/optimizer/_scipy_scalar.py,sha256=YmErX4s_ywVIn861-D06d-TvDWi0rp843Jit3x80qtU,3202
|
|
34
34
|
pyfemtet/opt/parameter.py,sha256=YLE9lmYRaZA8isnTPJnbYXpUn6zsJFW4xg03QaSWey8,3950
|
|
@@ -36,7 +36,6 @@ pyfemtet/opt/prediction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
36
36
|
pyfemtet/opt/prediction/base.py,sha256=q4lDqrOtAkiWG-OblQEddnEVj29Q-EJE3-O5QTOb3Q4,1761
|
|
37
37
|
pyfemtet/opt/prediction/single_task_gp.py,sha256=VbsVllzXzCGqkM1fC61Ouqwuv3ddS5INbFwDG8v-d6g,3303
|
|
38
38
|
pyfemtet/opt/samples/femprj_sample/.gitignore,sha256=hx-5Hhaf7kpHe1wvWWfJqjPfObg-zf9CTI4joNh2Hk4,28
|
|
39
|
-
pyfemtet/opt/samples/femprj_sample/ParametricIF - True.femprj,sha256=tCd29CUXmyJ0VH6cV0xTdjQMLBPkCk0UrFwvRbyrcYA,431415
|
|
40
39
|
pyfemtet/opt/samples/femprj_sample/ParametricIF.femprj,sha256=9BtDHmc3cdom0Zq33DTdZ0mDAsIUY6i8SRkkg-n7GO0,442090
|
|
41
40
|
pyfemtet/opt/samples/femprj_sample/ParametricIF.py,sha256=oXzchBZEbH69xacDht5HDnbZzKwapXsn6bp9qihY17Y,707
|
|
42
41
|
pyfemtet/opt/samples/femprj_sample/ParametricIF_test_result.reccsv,sha256=TiOAqEDMub6SCGYClBv1JvQxphDOY3iIdr_pMmGgJ9M,2859
|
|
@@ -48,6 +47,9 @@ pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.SLDPRT,sha256=jjBi4aRRwZPK-4-YRKD
|
|
|
48
47
|
pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.femprj,sha256=knN0bBTHm5CqExLdmxdJvPldJ6ahnQesKt974qRjWh4,126837
|
|
49
48
|
pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.py,sha256=JoGQSwH3yJnABxyd-WJfrwMkhd1UV0yYF2L2RvMFXmc,4559
|
|
50
49
|
pyfemtet/opt/samples/femprj_sample/cad_ex01_SW_test_result.reccsv,sha256=NS0Zik2c1mbMdGa0hGJaRQdCD08Bltx84n9QzP5CjPo,4736
|
|
50
|
+
pyfemtet/opt/samples/femprj_sample/constrained_pipe.femprj,sha256=MAl-VQfethwYvl49RkuW7FQlFCQ9_mYvc03SsqBCad0,57414
|
|
51
|
+
pyfemtet/opt/samples/femprj_sample/constrained_pipe.py,sha256=-9LYdLQ4MEsdt9FAzaqhtRPwBQN5mnsXcOMyNqsv5Iw,3217
|
|
52
|
+
pyfemtet/opt/samples/femprj_sample/constrained_pipe_test_result.reccsv,sha256=AbAMXLtxrEBHLjdM0HnGQ7j3uJtVHZpxOZxOqNmO1CA,1796
|
|
51
53
|
pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.femprj,sha256=dbanN3W2eX_ciZ0wZGqK60mc4edSVh5G2OqbbMKyFng,74898
|
|
52
54
|
pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.py,sha256=RxLSXFs0SqUjlug_JZAKlkJhqJdQCY3Y3F-DtSQRtVM,2458
|
|
53
55
|
pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric_test_result.reccsv,sha256=NOaYmpmrhn9WMbIaLWFlR0IvRheGqcqu0J9Nf3JQnfo,1131
|
|
@@ -71,6 +73,7 @@ pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.femprj,sha256=0RBhOGhtiFAp0
|
|
|
71
73
|
pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.py,sha256=B7wVemkiVzh0NJXDzG3fdigWBOb58ZxrJZUT4NRvW9Q,4899
|
|
72
74
|
pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.femprj,sha256=ZZhT9XjB9Xu9YwHWv4gbvKBiUWlOFKEoHjAcGWb3vvQ,128026
|
|
73
75
|
pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.py,sha256=e-XaHBZ8syWlG9pObcDDkHGLC5t338zAt_NyRXty338,4837
|
|
76
|
+
pyfemtet/opt/samples/femprj_sample_jp/constrained_pipe_jp.py,sha256=QhAwJOFEknf6Yk3mMgr1gdqB_Db8akjJGZNBepsrdgA,3654
|
|
74
77
|
pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.femprj,sha256=PzqtNVde6VnMHFpedRBsOq9JVhCY0ymQPVs54EKsNLw,75668
|
|
75
78
|
pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.py,sha256=97np4uH-UQqpv4UDwJS0doFYA7TOkXnbhLdkZExdNek,2461
|
|
76
79
|
pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.femprj,sha256=TTXw_8YT8pzHQlu4ufGzTq1IFYSwcWWt4GA6sIY1YPM,295600
|
|
@@ -105,8 +108,8 @@ pyfemtet/opt/visualization/wrapped_components/dbc.py,sha256=wzR1ZMOb4uwPNTMFn5up
|
|
|
105
108
|
pyfemtet/opt/visualization/wrapped_components/dcc.py,sha256=hcW7SR6VIMn4S4-JMyohvOzdc0Aw8A4chIeHqQEUbFU,17499
|
|
106
109
|
pyfemtet/opt/visualization/wrapped_components/html.py,sha256=sE2XHTDY1GvA1NW7y6SKWf-WglVXFKKvXhU9h3z53_g,95652
|
|
107
110
|
pyfemtet/opt/visualization/wrapped_components/str_enum.py,sha256=NZqbh2jNEAckvJyZv__MWeRs2F2Q-dkJCWo30rU2rrM,1383
|
|
108
|
-
pyfemtet-0.5.
|
|
109
|
-
pyfemtet-0.5.
|
|
110
|
-
pyfemtet-0.5.
|
|
111
|
-
pyfemtet-0.5.
|
|
112
|
-
pyfemtet-0.5.
|
|
111
|
+
pyfemtet-0.5.2.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
|
|
112
|
+
pyfemtet-0.5.2.dist-info/METADATA,sha256=jdH1UdFRexWUeZ9saoDfjoFmw55OkOlGp6fLDxHJyTg,3287
|
|
113
|
+
pyfemtet-0.5.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
114
|
+
pyfemtet-0.5.2.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
|
|
115
|
+
pyfemtet-0.5.2.dist-info/RECORD,,
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|