pyfemtet 0.4.19__py3-none-any.whl → 0.4.21__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.

@@ -215,6 +215,24 @@ class FemtetInterface(FEMInterface):
215
215
  if self.Femtet is None:
216
216
  raise RuntimeError(Msg.ERR_FEMTET_CONNECTION_FAILED)
217
217
 
218
+ def _check_gaudi_accessible(self) -> bool:
219
+ try:
220
+ _ = self.Femtet.Gaudi
221
+ except com_error:
222
+ # モデルが開かれていないかFemtetが起動していない
223
+ return False
224
+ return True
225
+
226
+ # noinspection PyMethodMayBeStatic
227
+ def _construct_femtet_api(self, string): # static にしてはいけない
228
+ if isinstance(string, str):
229
+ if string.startswith('self.'):
230
+ return eval(string)
231
+ else:
232
+ return eval('self.' + string)
233
+ else:
234
+ return string # Callable
235
+
218
236
  def _call_femtet_api(
219
237
  self,
220
238
  fun,
@@ -232,7 +250,7 @@ class FemtetInterface(FEMInterface):
232
250
 
233
251
  Parameters
234
252
  ----------
235
- fun : Callable
253
+ fun : Callable or str
236
254
  Femtet API
237
255
  return_value_if_failed : Any
238
256
  API が失敗した時の戻り値
@@ -271,36 +289,62 @@ class FemtetInterface(FEMInterface):
271
289
  # 1. 結果に関わらず戻り値が None で API 実行時に com_error を送出する
272
290
  # 2. API 実行時に成功失敗を示す戻り値を返し、ShowLastError で例外にアクセスできる状態になる
273
291
 
292
+ # 実行する API をデバッグ出力
293
+ if isinstance(fun, str):
294
+ logger.debug(' ' * print_indent + f'Femtet API:{fun}, args:{args}, kwargs:{kwargs}')
295
+ else:
296
+ logger.debug(' ' * print_indent + f'Femtet API:{fun.__name__}, args:{args}, kwargs:{kwargs}')
297
+
274
298
  # Gaudi コマンドなら Gaudi.Activate する
275
- logger.debug(' ' * print_indent + f'Femtet API:{fun.__name__}, args:{args}, kwargs:{kwargs}')
276
299
  if is_Gaudi_method: # Optimizer は Gogh に触らないので全部にこれをつけてもいい気がする
277
300
  try:
278
- self._call_femtet_api(
279
- self.Femtet.Gaudi.Activate,
280
- False, # None 以外なら何でもいい
281
- Exception,
282
- 'Gaudi のオープンに失敗しました',
283
- print_indent=print_indent + 1
284
- )
301
+ # まず Gaudi にアクセスできるか
302
+ gaudi_accessible = self._check_gaudi_accessible()
303
+ if gaudi_accessible:
304
+ # Gaudi にアクセスできるなら Gaudi を Activate する
305
+ fun = self._construct_femtet_api(fun) # (str) -> Callable
306
+ if fun.__name__ != 'Activate':
307
+ # 再帰ループにならないように
308
+ self._call_femtet_api(
309
+ self.Femtet.Gaudi.Activate,
310
+ False, # None 以外なら何でもいい
311
+ Exception,
312
+ 'Gaudi のオープンに失敗しました',
313
+ print_indent=print_indent + 1
314
+ )
315
+
316
+ else:
317
+ # Gaudi にアクセスできないならば次の API 実行でエラーになる
318
+ pass
319
+
285
320
  except com_error:
286
- # Gaudi へのアクセスだけで com_error が生じうる
287
- # そういう場合は次の API 実行で間違いなくエラーになるので放っておく
288
321
  pass
289
322
 
290
323
  # API を実行
291
324
  try:
325
+ # gaudi のメソッドかどうかにかかわらず、gaudi へのアクセスでエラーが出るか
326
+ if not self._check_gaudi_accessible():
327
+ raise com_error
328
+
329
+ # gaudi_accessible なので関数が何であろうが安全にアクセスはできる
330
+ if isinstance(fun, str):
331
+ fun = self._construct_femtet_api(fun) # (str) -> Callable
332
+
292
333
  # 解析結果を開いた状態で Gaudi.Activate して ReExecute する場合、ReExecute の前後にアクティブ化イベントが必要
293
334
  # さらに、プロジェクトツリーが開いていないとアクティブ化イベントも意味がないらしい。
294
335
  if fun.__name__ == 'ReExecute':
295
336
  if self.open_result_with_gui or self.parametric_output_indexes_use_as_objective:
296
337
  post_activate_message(self.Femtet.hWnd)
338
+ # API を実行
297
339
  returns = fun(*args, **kwargs) # can raise pywintypes.error
298
340
  if self.open_result_with_gui or self.parametric_output_indexes_use_as_objective:
299
341
  post_activate_message(self.Femtet.hWnd)
300
342
  else:
301
343
  returns = fun(*args, **kwargs)
344
+
345
+ # API の実行に失敗
302
346
  except (com_error, error):
303
- # パターン 2 エラーが生じたことは確定なのでエラーが起こるよう returns を作る
347
+ # 後続の処理でエラー判定されるように returns を作る
304
348
  # com_error ではなく error の場合はおそらく Femtet が落ちている
305
349
  if ret_for_check_idx is None:
306
350
  returns = return_value_if_failed
@@ -361,7 +405,7 @@ class FemtetInterface(FEMInterface):
361
405
 
362
406
  def femtet_is_alive(self) -> bool:
363
407
  """Returns connected femtet process is existing or not."""
364
- return _get_pid(self.Femtet.hWnd) > 0
408
+ return _get_pid(self.Femtet.hWnd) > 0 # hWnd の値はすでに Femtet が終了している場合は 0
365
409
 
366
410
  def open(self, femprj_path: str, model_name: str or None = None) -> None:
367
411
  """Open specific analysis model with connected Femtet."""
@@ -479,7 +523,7 @@ class FemtetInterface(FEMInterface):
479
523
  # 変数更新のための処理
480
524
  sleep(0.1) # Gaudi がおかしくなる時がある対策
481
525
  self._call_femtet_api(
482
- self.Femtet.Gaudi.Activate,
526
+ 'self.Femtet.Gaudi.Activate',
483
527
  True, # 戻り値を持たないのでここは無意味で None 以外なら何でもいい
484
528
  Exception, # 生きてるのに開けない場合
485
529
  error_message=Msg.NO_ANALYSIS_MODEL_IS_OPEN,
@@ -553,7 +597,7 @@ class FemtetInterface(FEMInterface):
553
597
 
554
598
  # 設計変数に従ってモデルを再構築
555
599
  self._call_femtet_api(
556
- self.Femtet.Gaudi.ReExecute,
600
+ 'self.Femtet.Gaudi.ReExecute',
557
601
  False,
558
602
  ModelError, # 生きてるのに失敗した場合
559
603
  error_message=Msg.ERR_RE_EXECUTE_MODEL_FAILED,
@@ -576,7 +620,7 @@ class FemtetInterface(FEMInterface):
576
620
  """Execute FEM analysis."""
577
621
  # # メッシュを切る
578
622
  self._call_femtet_api(
579
- self.Femtet.Gaudi.Mesh,
623
+ 'self.Femtet.Gaudi.Mesh',
580
624
  0,
581
625
  MeshError,
582
626
  Msg.ERR_MODEL_MESH_FAILED,
@@ -630,6 +674,11 @@ class FemtetInterface(FEMInterface):
630
674
  def quit(self, timeout=1, force=True):
631
675
  """Force to terminate connected Femtet."""
632
676
  major, minor, bugfix = 2024, 0, 1
677
+
678
+ # すでに終了しているならば何もしない
679
+ if not self.femtet_is_alive():
680
+ return
681
+
633
682
  if self._version() >= _version(major, minor, bugfix):
634
683
  # gracefully termination method without save project available from 2024.0.1
635
684
  try:
@@ -715,16 +764,20 @@ class FemtetInterface(FEMInterface):
715
764
  # save to worker space
716
765
  result_dir = self.femprj_path.replace('.femprj', '.Results')
717
766
  pdt_path = os.path.join(result_dir, self.model_name + '.pdt')
718
- succeed = self.Femtet.SavePDT(pdt_path, True)
719
767
 
720
- # convert .pdt to ByteIO
721
- if succeed:
722
- with open(pdt_path, 'rb') as f:
723
- content = f.read()
724
- return content
768
+ self._call_femtet_api(
769
+ fun=self.Femtet.SavePDT,
770
+ args=(pdt_path, True),
771
+ return_value_if_failed=False,
772
+ if_error=SolveError,
773
+ error_message=Msg.ERR_FAILED_TO_SAVE_PDT,
774
+ is_Gaudi_method=False,
775
+ )
725
776
 
726
- else:
727
- raise Exception(Msg.ERR_FAILED_TO_SAVE_PDT)
777
+ # convert .pdt to ByteIO and return it
778
+ with open(pdt_path, 'rb') as f:
779
+ content = f.read()
780
+ return content
728
781
 
729
782
  else:
730
783
  return None
pyfemtet/opt/opt/_base.py CHANGED
@@ -1,5 +1,6 @@
1
1
  # typing
2
2
  from abc import ABC, abstractmethod
3
+ from typing import Optional
3
4
 
4
5
  # built-in
5
6
  import traceback
@@ -13,6 +14,7 @@ import pandas as pd
13
14
  from pyfemtet.opt.interface import FemtetInterface
14
15
  from pyfemtet.opt._femopt_core import OptimizationStatus
15
16
  from pyfemtet.message import Msg
17
+ from pyfemtet.opt.parameter import ExpressionEvaluator
16
18
 
17
19
  # logger
18
20
  import logging
@@ -134,6 +136,7 @@ class AbstractOptimizer(ABC):
134
136
  self.fem_class = None
135
137
  self.fem_kwargs = dict()
136
138
  self.parameters: pd.DataFrame = pd.DataFrame()
139
+ self.variables: ExpressionEvaluator = ExpressionEvaluator()
137
140
  self.objectives: dict = dict()
138
141
  self.constraints: dict = dict()
139
142
  self.entire_status = None # actor
@@ -153,14 +156,22 @@ class AbstractOptimizer(ABC):
153
156
  # interruption の実装は具象クラスに任せる
154
157
 
155
158
  # x の更新
156
- self.parameters['value'] = x
159
+ prm_names = self.variables.get_parameter_names()
160
+ for name, value in zip(prm_names, x):
161
+ self.variables.variables[name].value = value
162
+
157
163
  logger.info('---------------------')
158
164
  logger.info(f'input: {x}')
159
165
 
160
166
  # FEM の更新
161
167
  logger.debug('fem.update() start')
162
168
  try:
163
- self.fem.update(self.parameters)
169
+ df_to_fem = self.variables.get_variables(
170
+ format='df',
171
+ filter_pass_to_fem=True
172
+ )
173
+ self.fem.update(df_to_fem)
174
+
164
175
  except Exception as e:
165
176
  logger.info(f'{type(e).__name__} : {e}')
166
177
  logger.info(Msg.INFO_EXCEPTION_DURING_FEM_ANALYSIS)
@@ -178,8 +189,14 @@ class AbstractOptimizer(ABC):
178
189
  c = [cns.calc(self.fem) for cns in self.constraints.values()]
179
190
 
180
191
  logger.debug('history.record start')
192
+
193
+ df_to_opt = self.variables.get_variables(
194
+ format='df',
195
+ filter_parameter=True,
196
+ )
197
+
181
198
  self.history.record(
182
- self.parameters,
199
+ df_to_opt,
183
200
  self.objectives,
184
201
  self.constraints,
185
202
  y,
@@ -220,17 +237,7 @@ class AbstractOptimizer(ABC):
220
237
  ValueError: If an invalid format is provided.
221
238
 
222
239
  """
223
- if format == 'df':
224
- return self.parameters
225
- elif format == 'values' or format == 'value':
226
- return self.parameters.value.values
227
- elif format == 'dict':
228
- ret = {}
229
- for i, row in self.parameters.iterrows():
230
- ret[row['name']] = row.value
231
- return ret
232
- else:
233
- raise ValueError(f'get_parameter() got invalid format: {format}')
240
+ return self.variables.get_variables(format=format)
234
241
 
235
242
  def _check_interruption(self):
236
243
  """"""
@@ -63,19 +63,25 @@ class OptunaOptimizer(AbstractOptimizer):
63
63
  trial.study.stop() # 現在実行中の trial を最後にする
64
64
  return None # set TrialState FAIL
65
65
 
66
- # candidate x
67
- x = []
68
- for i, row in self.parameters.iterrows():
69
- v = trial.suggest_float(row['name'], row['lb'], row['ub'], step=row['step'])
70
- x.append(v)
71
- x = np.array(x).astype(float)
66
+ # candidate x and update parameters
67
+ for prm in self.variables.get_variables(format='raw', filter_parameter=True):
68
+ value = trial.suggest_float(
69
+ name=prm.name,
70
+ low=prm.lower_bound,
71
+ high=prm.upper_bound,
72
+ step=prm.step,
73
+ )
74
+ self.variables.variables[prm.name].value = value
75
+
76
+ # update expressions
77
+ self.variables.evaluate()
72
78
 
73
79
  # message の設定
74
80
  self.message = trial.user_attrs['message'] if 'message' in trial.user_attrs.keys() else ''
75
81
 
76
- # fem や opt 経由で変数を取得して constraint を計算する時のためにアップデート
77
- self.parameters['value'] = x
78
- self.fem.update_parameter(self.parameters)
82
+ # fem 経由で変数を取得して constraint を計算する時のためにアップデート
83
+ df_fem = self.variables.get_variables(format='df', filter_pass_to_fem=True)
84
+ self.fem.update_parameter(df_fem)
79
85
 
80
86
  # strict 拘束
81
87
  strict_constraints = [cns for cns in self.constraints.values() if cns.strict]
@@ -89,10 +95,11 @@ class OptunaOptimizer(AbstractOptimizer):
89
95
  if not feasible:
90
96
  logger.info(Msg.INFO_INFEASIBLE)
91
97
  logger.info(f'Constraint: {cns.name}')
92
- logger.info(self.get_parameter('dict'))
98
+ logger.info(self.variables.get_variables('dict', filter_parameter=True))
93
99
  raise optuna.TrialPruned() # set TrialState PRUNED because FAIL causes similar candidate loop.
94
100
 
95
101
  # 計算
102
+ x = self.variables.get_variables(format='values', filter_parameter=True)
96
103
  try:
97
104
  _, _y, c = self.f(x) # f の中で info は出している
98
105
  except (ModelError, MeshError, SolveError) as e:
@@ -175,7 +182,7 @@ class OptunaOptimizer(AbstractOptimizer):
175
182
  # 初期値の設定
176
183
  if len(self.study.trials) == 0: # リスタートでなければ
177
184
  # ユーザーの指定した初期値
178
- params = self.get_parameter('dict')
185
+ params = self.variables.get_variables('dict', filter_parameter=True)
179
186
  self.study.enqueue_trial(params, user_attrs={"message": "initial"})
180
187
 
181
188
  # add_initial_parameter で追加された初期値
@@ -197,8 +204,8 @@ class OptunaOptimizer(AbstractOptimizer):
197
204
  bounds = []
198
205
  for i, row in self.parameters.iterrows():
199
206
  names.append(row['name'])
200
- lb = row['lb']
201
- ub = row['ub']
207
+ lb = row['lower_bound']
208
+ ub = row['upper_bound']
202
209
  bounds.append([lb, ub])
203
210
  data = generate_lhs(bounds, seed=self.seed)
204
211
  for datum in data:
@@ -114,7 +114,7 @@ class ScipyOptimizer(AbstractOptimizer):
114
114
  if 'bounds' not in self.minimize_kwargs.keys():
115
115
  bounds = []
116
116
  for i, row in self.parameters.iterrows():
117
- lb, ub = row['lb'], row['ub']
117
+ lb, ub = row['lower_buond'], row['upper_bound']
118
118
  if lb is None: lb = -np.inf
119
119
  if ub is None: ub = np.inf
120
120
  bounds.append([lb, ub])
@@ -78,7 +78,7 @@ class ScipyScalarOptimizer(AbstractOptimizer):
78
78
  if 'bounds' not in self.minimize_kwargs.keys():
79
79
  bounds = []
80
80
  for i, row in self.parameters.iterrows():
81
- lb, ub = row['lb'], row['ub']
81
+ lb, ub = row['lower_bound'], row['upper_bound']
82
82
  if lb is None: lb = -np.inf
83
83
  if ub is None: ub = np.inf
84
84
  bounds.append([lb, ub])
@@ -0,0 +1,113 @@
1
+ from graphlib import TopologicalSorter
2
+ from dataclasses import dataclass
3
+ import inspect
4
+ from typing import Optional, Callable, Any, Tuple, Dict
5
+
6
+ import numpy as np
7
+ import pandas as pd
8
+
9
+
10
+ @dataclass
11
+ class Variable:
12
+ name: str
13
+ value: float
14
+ pass_to_fem: Optional[bool] = True
15
+ properties: Optional[dict[Any]] = None
16
+
17
+
18
+ @dataclass
19
+ class Parameter(Variable):
20
+ lower_bound: Optional[float] = None
21
+ upper_bound: Optional[float] = None
22
+ step: Optional[float] = None
23
+
24
+
25
+ @dataclass
26
+ class Expression(Variable):
27
+ # fun に params を自動で代入するので positional args は実装しない
28
+ fun: Optional[Callable] = None
29
+ kwargs: Optional[Dict] = None
30
+
31
+
32
+ class ExpressionEvaluator:
33
+ def __init__(self):
34
+ self.variables = {} # Parameter 又は計算された Expression が入る
35
+ self.parameters = {}
36
+ self.expressions = {}
37
+ self.dependencies = {}
38
+ self.evaluation_order = []
39
+
40
+ def add_parameter(self, prm: Parameter):
41
+ self.variables[prm.name] = prm
42
+ self.parameters[prm.name] = prm
43
+ self.dependencies[prm.name] = set()
44
+
45
+ def add_expression(self, exp: Expression):
46
+ self.expressions[exp.name] = exp
47
+
48
+ # params は Python 変数として使える文字のみからなる文字列のリスト
49
+ params = inspect.signature(exp.fun).parameters
50
+ self.dependencies[exp.name] = set(params) - set(exp.kwargs.keys())
51
+
52
+ def resolve(self):
53
+ ts = TopologicalSorter(self.dependencies)
54
+ self.evaluation_order = list(ts.static_order())
55
+
56
+ def evaluate(self):
57
+ # order 順に見ていき、expression なら計算して variables を更新する
58
+ for var_name in self.evaluation_order:
59
+ if var_name in self.expressions.keys():
60
+ # 現在の expression に関して parameter 部分の引数 kwargs を作成
61
+ kwargs = {param: self.variables[param].value for param in self.dependencies[var_name]}
62
+
63
+ # fun に すべての kwargs を入れて expression の value を更新
64
+ exp: Expression = self.expressions[var_name]
65
+ kwargs.update(exp.kwargs)
66
+ exp.value = exp.fun(**kwargs)
67
+
68
+ # 計算済み variables に追加
69
+ self.variables[var_name] = exp
70
+
71
+ def get_variables(self, format='dict', filter_pass_to_fem=False, filter_parameter=False):
72
+ """format: dict, values, df, raw(list of Variable object)"""
73
+
74
+ # リストを作成
75
+ vars = [self.variables[name] for name in self.evaluation_order if name in self.variables]
76
+
77
+ # 必要なら FEM に直接使うもののみ取り出し
78
+ if filter_pass_to_fem:
79
+ vars = [var for var in vars if var.pass_to_fem]
80
+
81
+ # 必要なら parameter のみ取り出し
82
+ if filter_parameter:
83
+ vars = [var for var in vars if isinstance(var, Parameter)]
84
+
85
+ if format == 'raw':
86
+ return vars
87
+
88
+ elif format == 'dict':
89
+ return {var.name: var.value for var in vars}
90
+
91
+ elif format == 'values':
92
+ return np.array([var.value for var in vars]).astype(float)
93
+
94
+ elif format == 'df':
95
+ data = dict(
96
+ name=[var.name for var in vars],
97
+ value=[var.value for var in vars],
98
+ properties=[var.properties for var in vars],
99
+ )
100
+ if filter_parameter:
101
+ data.update(
102
+ dict(
103
+ lower_bound=[var.lower_bound for var in vars],
104
+ upper_bound=[var.upper_bound for var in vars],
105
+ )
106
+ )
107
+ return pd.DataFrame(data)
108
+
109
+ else:
110
+ raise NotImplementedError(f'invalid format: {format}. Valid formats are `dict`, `values`, `df` and `raw`(= list of Variables).')
111
+
112
+ def get_parameter_names(self):
113
+ return list(self.parameters.keys())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyfemtet
3
- Version: 0.4.19
3
+ Version: 0.4.21
4
4
  Summary: Design parameter optimization using Femtet.
5
5
  Home-page: https://github.com/pyfemtet/pyfemtet
6
6
  License: BSD-3-Clause
@@ -16,7 +16,7 @@ Requires-Dist: babel (>=2.15.0,<3.0.0)
16
16
  Requires-Dist: botorch (>=0.9.5) ; python_version >= "3.12" and python_version < "3.13"
17
17
  Requires-Dist: botorch (>=0.9.5,<0.10.0) ; python_version < "3.12"
18
18
  Requires-Dist: colorlog (>=6.8.0,<7.0.0)
19
- Requires-Dist: dash (>=2.14.2,<3.0.0)
19
+ Requires-Dist: dash (>=2.17.0,<3.0.0)
20
20
  Requires-Dist: dash-bootstrap-components (>=1.5.0,<2.0.0)
21
21
  Requires-Dist: dask (>=2023.12.1,<2024.0.0)
22
22
  Requires-Dist: distributed (>=2023.12.1,<2024.0.0)
@@ -26,11 +26,12 @@ Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
26
26
  Requires-Dist: optuna (>=3.4.0,<4.0.0)
27
27
  Requires-Dist: optuna-integration (>=3.6.0,<4.0.0)
28
28
  Requires-Dist: pandas (>=2.1.3,<3.0.0)
29
- Requires-Dist: plotly (>=5.18.0,<6.0.0)
29
+ Requires-Dist: plotly (>=5.22.0,<6.0.0)
30
30
  Requires-Dist: psutil (>=5.9.6,<6.0.0)
31
31
  Requires-Dist: pytest-dashboard (>=0.1.2,<0.2.0)
32
32
  Requires-Dist: pywin32 (>=306,<307)
33
33
  Requires-Dist: scipy (>=1.11.4,<2.0.0)
34
+ Requires-Dist: torch (>=2.3.0,<2.4.0)
34
35
  Requires-Dist: tqdm (>=4.66.1,<5.0.0)
35
36
  Project-URL: Repository, https://github.com/pyfemtet/pyfemtet
36
37
  Description-Content-Type: text/markdown
@@ -12,7 +12,7 @@ pyfemtet/FemtetPJTSample/her_ex40_parametric.py,sha256=B5PQoh71Q3KN2CyLU1gP_Yh9g
12
12
  pyfemtet/FemtetPJTSample/wat_ex14_parallel_parametric.py,sha256=UfhJffuXyhzdIWNpOrpV6xLTK1fuVvgyhlyg4Rp-628,2148
13
13
  pyfemtet/FemtetPJTSample/wat_ex14_parametric.femprj,sha256=pxacKe0NPNUPAcxqo2cATFApsMKiVt2g2e_FOk4fpjA,172895
14
14
  pyfemtet/FemtetPJTSample/wat_ex14_parametric.py,sha256=LGbWxCek0Ad2YrDCKykiQkE3aIypM4g8P3mLd_2anEE,2052
15
- pyfemtet/__init__.py,sha256=OCiQi0NygMAlBjlUUnm1SyRHaOf3qlZ_qx2T9-TEFkQ,22
15
+ pyfemtet/__init__.py,sha256=1n-NaGbhCs2-5sTHYY-kUYdFODaECYkQxiDw4p6nNng,22
16
16
  pyfemtet/_test_util.py,sha256=CT9J19qQ4gYT5glFs8WwlTDmc3SokvdE5ucpB-KCOro,4274
17
17
  pyfemtet/core.py,sha256=3lqfBGJ5IuKz2Nqj5pRo7YQqKwx_0ZDL72u95Ur_1p0,1386
18
18
  pyfemtet/dispatch_extensions.py,sha256=XVZajbjh7mb6NG4Hq8qff2TJWab75r4Hd59cIvCRsVg,16213
@@ -21,13 +21,13 @@ pyfemtet/message/1. make_pot.bat,sha256=oS38xYsaUnQAuKwUR8hZJFgt3AKBU993fWFDSg2R
21
21
  pyfemtet/message/2. make_mo.bat,sha256=nqUi3Cze7JGKkYItlch8ZG2gSbRNZiS2ltuCS7DbmG8,154
22
22
  pyfemtet/message/__init__.py,sha256=gE1-XX_PzHj9BbhqPaK5VcIHuv6_Tec5qlPMC3IRiBg,100
23
23
  pyfemtet/message/babel.cfg,sha256=rlvsm_EjDU2ki-OLVPG3toWspVuVA0JFAFvFp2U-By4,72
24
- pyfemtet/message/locales/ja/LC_MESSAGES/messages.mo,sha256=02THhFHvbWT9tWr-M3isYXbjF6-U6rLf9wh-Q8d-EEU,16595
25
- pyfemtet/message/locales/ja/LC_MESSAGES/messages.po,sha256=KwWy1qFgaf7Xewk3rV8ht3mNPEdPXPJmukdcqS4uuJs,21116
26
- pyfemtet/message/locales/messages.pot,sha256=CLjvfugvP8O-E6819gd3CmqZVYiwPGwU5kxOUpdukqY,12089
24
+ pyfemtet/message/locales/ja/LC_MESSAGES/messages.mo,sha256=VbUncnHf3ztDF3WqaoNd4AcGqpYKLMEKc1LL5P4yuoQ,16965
25
+ pyfemtet/message/locales/ja/LC_MESSAGES/messages.po,sha256=6UtCDxiDiRetnnSRo-l_BunYfYoIm0L-9Z8qU3r8z8Q,21723
26
+ pyfemtet/message/locales/messages.pot,sha256=JWknwqPn_541aeIEbxp9Y2tqXvUcoM-vgdjeUo4C2T0,12336
27
27
  pyfemtet/message/messages.py,sha256=GCzjA6dBLI8108K3hel82pcr1nYTvjJKCfCAn5jZ5OM,11324
28
28
  pyfemtet/opt/__init__.py,sha256=AJc1_d0sQ2_X4h_8FOcdmHvSPrFV_vfxlRrZTsqDZuE,612
29
- pyfemtet/opt/_femopt.py,sha256=LE6ImEyCFRqBpSLkTfgEykjw1gltu59bd3ZB5lE1vjk,23373
30
- pyfemtet/opt/_femopt_core.py,sha256=X_hIbf0ifiXFv_ADRiRzlyQPHK_Hzyd7xEday7ATvzY,25293
29
+ pyfemtet/opt/_femopt.py,sha256=lJJYDNoeAFlPEDD7mMz5PXA-x91vz6u0hnai7FLJJ30,24905
30
+ pyfemtet/opt/_femopt_core.py,sha256=ezf-E1_oaupSgHb0mwPooV0nvsrQC1wgtumN5WzQop8,25311
31
31
  pyfemtet/opt/femprj_sample/.gitignore,sha256=hx-5Hhaf7kpHe1wvWWfJqjPfObg-zf9CTI4joNh2Hk4,28
32
32
  pyfemtet/opt/femprj_sample/ParametricIF - True.femprj,sha256=tCd29CUXmyJ0VH6cV0xTdjQMLBPkCk0UrFwvRbyrcYA,431415
33
33
  pyfemtet/opt/femprj_sample/ParametricIF.femprj,sha256=9BtDHmc3cdom0Zq33DTdZ0mDAsIUY6i8SRkkg-n7GO0,442090
@@ -109,17 +109,18 @@ pyfemtet/opt/femprj_sample_jp/wat_ex14_parametric_jp.py,sha256=W30jobW1eEYuAsJJR
109
109
  pyfemtet/opt/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py,sha256=ul2JUwlM5jfjNRELHkT7ZDuyMOq5RAHO32vAweEhCwg,2641
110
110
  pyfemtet/opt/interface/__init__.py,sha256=qz5BszPuU3jZIoDnPjkPDAgvgHLlx1sYhuqh5ID798k,480
111
111
  pyfemtet/opt/interface/_base.py,sha256=I4pJttLeRW-6WWMuCNynwxWPwriiGZk20vHLVcfixZY,2332
112
- pyfemtet/opt/interface/_femtet.py,sha256=U5sRe8yMsc4Uum_hRGl0C6S8A04a_p388q39d4lHsng,32388
112
+ pyfemtet/opt/interface/_femtet.py,sha256=vWPEn8TpJFCSN48uk430kAFr7_5ralMoOGF8IKvpIjU,34441
113
113
  pyfemtet/opt/interface/_femtet_parametric.py,sha256=KDG8SB43AgwuhpCStjvx10G0RzyHhga6k4dfvp0gvYU,2175
114
114
  pyfemtet/opt/interface/_femtet_with_nx/__init__.py,sha256=-6W2g2FDEcKzGHmI5KAKQe-4U5jDpMj0CXuma-GZca0,83
115
115
  pyfemtet/opt/interface/_femtet_with_nx/_interface.py,sha256=cibPOhsUAvTDJa1xdEhVClZjwPkEx2kBmi61vyTJHUs,5514
116
116
  pyfemtet/opt/interface/_femtet_with_nx/update_model.py,sha256=P7VH0i_o-X9OUe6AGaLF1fACPeHNrMjcrOBCA3MMrI4,3092
117
117
  pyfemtet/opt/interface/_femtet_with_sldworks.py,sha256=Ldr8Esa5xZ-D_E5uIXBTF2DHslXVMFDYOsqTd8FhY1M,6242
118
118
  pyfemtet/opt/opt/__init__.py,sha256=_9hkYtxk-8PfWkWJaiYqESrH5CnSKM2Gv93HxtD-f3o,383
119
- pyfemtet/opt/opt/_base.py,sha256=LZp17pjkqEKoS4W4j2Vj4Afc9Y_Yv8p5fZ7m7nHkFC0,11273
120
- pyfemtet/opt/opt/_optuna.py,sha256=GFz7PcI8rPAiqqzK3hqjaL0WCAbA6gfN2tBYufXxPBQ,10701
121
- pyfemtet/opt/opt/_scipy.py,sha256=HkEZTjMRJvOoIWIpIEbJaZJjZQkQ73FjD9c4NZADeIc,4185
122
- pyfemtet/opt/opt/_scipy_scalar.py,sha256=6nFAnERtQIMnPJCwR5HkpKetxrVJaSFWHxJfXMPn3wg,2815
119
+ pyfemtet/opt/opt/_base.py,sha256=pIxreZzhT4YQOj7mtXnfidNqJ18ypZBpD2CK0G_uQ6Q,11425
120
+ pyfemtet/opt/opt/_optuna.py,sha256=y4MnFPDyP1eheq5nUh786z0BM-pHNYrSwjo1TD044h0,11105
121
+ pyfemtet/opt/opt/_scipy.py,sha256=8Alx9sIlLzNTxuVGTHOJMsvW5LSp8WDFiqD8IV6CVPc,4203
122
+ pyfemtet/opt/opt/_scipy_scalar.py,sha256=ot1KbetZeQh5XkllzHc1PubPjBPgVBtC0a4jllNi8G4,2833
123
+ pyfemtet/opt/parameter.py,sha256=YLE9lmYRaZA8isnTPJnbYXpUn6zsJFW4xg03QaSWey8,3950
123
124
  pyfemtet/opt/prediction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
124
125
  pyfemtet/opt/prediction/base.py,sha256=q4lDqrOtAkiWG-OblQEddnEVj29Q-EJE3-O5QTOb3Q4,1761
125
126
  pyfemtet/opt/prediction/single_task_gp.py,sha256=VbsVllzXzCGqkM1fC61Ouqwuv3ddS5INbFwDG8v-d6g,3303
@@ -145,8 +146,8 @@ pyfemtet/opt/visualization/wrapped_components/dbc.py,sha256=wzR1ZMOb4uwPNTMFn5up
145
146
  pyfemtet/opt/visualization/wrapped_components/dcc.py,sha256=hcW7SR6VIMn4S4-JMyohvOzdc0Aw8A4chIeHqQEUbFU,17499
146
147
  pyfemtet/opt/visualization/wrapped_components/html.py,sha256=sE2XHTDY1GvA1NW7y6SKWf-WglVXFKKvXhU9h3z53_g,95652
147
148
  pyfemtet/opt/visualization/wrapped_components/str_enum.py,sha256=NZqbh2jNEAckvJyZv__MWeRs2F2Q-dkJCWo30rU2rrM,1383
148
- pyfemtet-0.4.19.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
149
- pyfemtet-0.4.19.dist-info/METADATA,sha256=hRr5yBMmdzSVSaLV4hUA0kk9omm7SFpE-mT5ogpx6u4,3421
150
- pyfemtet-0.4.19.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
151
- pyfemtet-0.4.19.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
152
- pyfemtet-0.4.19.dist-info/RECORD,,
149
+ pyfemtet-0.4.21.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
150
+ pyfemtet-0.4.21.dist-info/METADATA,sha256=r0QpSmzWtYQ9Us_OsVe_cNJGRo8E6JKci0aL9SDD-qI,3459
151
+ pyfemtet-0.4.21.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
152
+ pyfemtet-0.4.21.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
153
+ pyfemtet-0.4.21.dist-info/RECORD,,