pyfemtet 0.8.9__py3-none-any.whl → 0.8.11__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 CHANGED
@@ -1 +1 @@
1
- __version__ = "0.8.9"
1
+ __version__ = "0.8.11"
@@ -7,7 +7,7 @@ msgid ""
7
7
  msgstr ""
8
8
  "Project-Id-Version: PROJECT VERSION\n"
9
9
  "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10
- "POT-Creation-Date: 2025-01-29 15:47+0900\n"
10
+ "POT-Creation-Date: 2025-02-19 13:47+0900\n"
11
11
  "PO-Revision-Date: 2024-07-22 14:05+0900\n"
12
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
13
  "Language: ja\n"
@@ -16,7 +16,7 @@ msgstr ""
16
16
  "MIME-Version: 1.0\n"
17
17
  "Content-Type: text/plain; charset=utf-8\n"
18
18
  "Content-Transfer-Encoding: 8bit\n"
19
- "Generated-By: Babel 2.16.0\n"
19
+ "Generated-By: Babel 2.17.0\n"
20
20
 
21
21
  #: pyfemtet/_message/messages.py:30
22
22
  msgid "hello!"
@@ -542,6 +542,14 @@ msgstr "ひとつの設計変数に対する目的関数の変化"
542
542
  msgid "The vertical axis is objective, and the horizontal axis is parameter."
543
543
  msgstr "縦軸は目的関数、横軸は設計変数です。"
544
544
 
545
+ #: pyfemtet/_message/messages.py:201
546
+ msgid "The importance of parameters evaluated by fANOVA"
547
+ msgstr "fANOVA に基づくパラメータ重要度"
548
+
549
+ #: pyfemtet/_message/messages.py:202
550
+ msgid "The normalized relative importance of parameters. Please note that the importance is calculated from the overall relationship of the input-output response, rather than from a specific solution."
551
+ msgstr "相対的なパラメータの重要度です。この重要度は特定の解におけるものではなく、入力-出力応答全体の関係から計算されていることに注意してください。"
552
+
545
553
  #~ msgid "The magnitude relationship is incorrect. "
546
554
  #~ msgstr ""
547
555
 
@@ -8,14 +8,14 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: PROJECT VERSION\n"
10
10
  "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
11
- "POT-Creation-Date: 2025-01-29 15:47+0900\n"
11
+ "POT-Creation-Date: 2025-02-19 13:47+0900\n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
15
  "MIME-Version: 1.0\n"
16
16
  "Content-Type: text/plain; charset=utf-8\n"
17
17
  "Content-Transfer-Encoding: 8bit\n"
18
- "Generated-By: Babel 2.16.0\n"
18
+ "Generated-By: Babel 2.17.0\n"
19
19
 
20
20
  #: pyfemtet/_message/messages.py:30
21
21
  msgid "hello!"
@@ -541,3 +541,11 @@ msgstr ""
541
541
  msgid "The vertical axis is objective, and the horizontal axis is parameter."
542
542
  msgstr ""
543
543
 
544
+ #: pyfemtet/_message/messages.py:201
545
+ msgid "The importance of parameters evaluated by fANOVA"
546
+ msgstr ""
547
+
548
+ #: pyfemtet/_message/messages.py:202
549
+ msgid "The normalized relative importance of parameters. Please note that the importance is calculated from the overall relationship of the input-output response, rather than from a specific solution."
550
+ msgstr ""
551
+
@@ -198,4 +198,5 @@ class Message:
198
198
  DETAIL_PAGE_CONTOUR_DESCRIPTION = _('The axes are parameters, and the color shows objective value.')
199
199
  DETAIL_PAGE_SLICE_HEADER = _('The response of an objective versus one parameter')
200
200
  DETAIL_PAGE_SLICE_DESCRIPTION = _('The vertical axis is objective, and the horizontal axis is parameter.')
201
-
201
+ DETAIL_PAGE_IMPORTANCE_HEADER = _('The importance of parameters evaluated by fANOVA')
202
+ DETAIL_PAGE_IMPORTANCE_DESCRIPTION = _('The normalized relative importance of parameters. Please note that the importance is calculated from the overall relationship of the input-output response, rather than from a specific solution.')
@@ -13,15 +13,15 @@ __all__ = [
13
13
  ]
14
14
 
15
15
 
16
- def parse_excel(book_path, sheet_name, keyword, required, optional) -> pd.DataFrame:
16
+ def parse_excel(book_path, sheet_name, keyword, required, optional, raise_if_no_keyword=True) -> pd.DataFrame:
17
17
  """Excel シートからパラメータを取得します。
18
18
 
19
19
  シートのパースプロセスは以下の通りです。
20
20
 
21
21
  1. シート全体 (A1 セルから、値が入力されている最終セルまで) をデータに取り込みます。
22
- 2. すべてのセルが空白である列をデータから除きます。
23
- 3. すべてのセルが空白である行をデータから除きます。
24
- 4. 最も左上(上が優先)にある keyword に一致するセルより上および左の行・列をデータから除きます。
22
+ 2. 最も左上(上が優先)にある keyword に一致するセルより上および左の行・列をデータから除きます。
23
+ 3. その時点のデータの上から順に見てすべてのセルが空白である行以下の行をデータから除きます。
24
+ 4. すべてのセルが空白である列をデータから除きます。
25
25
 
26
26
  Args:
27
27
  book_path: Excel book のパス。
@@ -29,6 +29,7 @@ def parse_excel(book_path, sheet_name, keyword, required, optional) -> pd.DataFr
29
29
  keyword (str): 必ず含まれるべき、表データの最初の列名として使う文字列。
30
30
  required (list[str]): 必ず含まれるべき、表データの列名として使う文字列のリスト。
31
31
  optional (list[str]): 表データの列名として使ってよい文字列のリスト。
32
+ raise_if_no_keyword (bool, optional): 指定されたシートに keyword が含まれない場合エラーにするかどうか。
32
33
 
33
34
  Returns:
34
35
 
@@ -41,21 +42,31 @@ def parse_excel(book_path, sheet_name, keyword, required, optional) -> pd.DataFr
41
42
  # 読み込み
42
43
  df = pd.read_excel(book_path, sheet_name, header=None)
43
44
 
44
- # NaN のみからなる列を削除する
45
- valid_columns = [col for col in df.columns if df[col].notna().sum()]
46
- df = df[valid_columns]
47
-
48
- # NaN のみからなる行を削除する
49
- valid_rows = [row for row in df.index if df.loc[row].notna().sum()]
50
- df = df.loc[valid_rows]
51
-
52
45
  # 「変数名」を左上とする表にする
53
- df: pd.DataFrame
54
46
  idx = np.where(df.values == keyword)
47
+ if len(idx[0]) == 0:
48
+ if raise_if_no_keyword:
49
+ raise RuntimeError(f'keyword "{keyword}" is lacked in {sheet_name}. ')
50
+ else:
51
+ return pd.DataFrame()
52
+
55
53
  r = idx[0][0]
56
54
  c = idx[1][0]
57
55
  df = pd.DataFrame(df.iloc[1+r:, c:].values, columns=df.iloc[r, c:].values)
58
56
 
57
+ # NaN のみからなる行を最初に見つけるまでデータに追加する
58
+ valid_rows = []
59
+ for row in df.index:
60
+ if df.loc[row].notna().sum():
61
+ valid_rows.append(row)
62
+ else:
63
+ break
64
+ df = df.loc[valid_rows]
65
+
66
+ # NaN のみからなる列を削除する
67
+ valid_columns = [col for i, col in enumerate(df.columns) if df.iloc[:, i].notna().sum()]
68
+ df = df[valid_columns]
69
+
59
70
  # パースが成功しているかチェックする
60
71
  lack = True
61
72
  for col in df.columns:
@@ -76,8 +87,15 @@ class ParseBase:
76
87
  OPTIONAL_COLUMNS = []
77
88
 
78
89
  @classmethod
79
- def parse(cls, book_path, sheet_name) -> pd.DataFrame:
80
- return parse_excel(book_path, sheet_name, cls.KEYWORD, cls.REQUIRED_COLUMNS, cls.OPTIONAL_COLUMNS)
90
+ def parse(cls, book_path, sheet_name, raise_if_no_keyword=True) -> pd.DataFrame:
91
+ return parse_excel(
92
+ book_path,
93
+ sheet_name,
94
+ cls.KEYWORD,
95
+ cls.REQUIRED_COLUMNS,
96
+ cls.OPTIONAL_COLUMNS,
97
+ raise_if_no_keyword,
98
+ )
81
99
 
82
100
 
83
101
  class ParseAsParameter(ParseBase):
pyfemtet/opt/_femopt.py CHANGED
@@ -139,6 +139,7 @@ class FEMOpt:
139
139
  self.monitor_host_record = None
140
140
  self._hv_reference = None
141
141
  self._extra_space_dir = None
142
+ self._opt_exceptions = []
142
143
 
143
144
  # multiprocess 時に pickle できないオブジェクト参照の削除
144
145
  def __getstate__(self):
@@ -925,6 +926,7 @@ class FEMOpt:
925
926
  sleep(1) # monitor が terminated 状態で少なくとも一度更新されなければ running のまま固まる
926
927
 
927
928
  # 全ての Exception を再表示
929
+ self._opt_exceptions = opt_exceptions
928
930
  for i, opt_exception in enumerate(opt_exceptions):
929
931
  if opt_exception is not None:
930
932
  print()
@@ -306,7 +306,7 @@ class Function:
306
306
  fun.__globals__[varname] = _Scapegoat()
307
307
 
308
308
  self.fun = fun
309
- self.name = name
309
+ self.name: str = name
310
310
  self.args = args
311
311
  self.kwargs = kwargs
312
312
 
@@ -325,7 +325,7 @@ class Function:
325
325
  args = self.args
326
326
  # Femtet 特有の処理
327
327
  if isinstance(fem, FemtetInterface):
328
- args = (fem.Femtet, *args)
328
+ args = (fem.object_passed_to_functions, *args)
329
329
  return float(self.fun(*args, **self.kwargs))
330
330
 
331
331
  def _restore_constants(self):
@@ -853,7 +853,7 @@ class History:
853
853
 
854
854
  # 最小化問題に変換された objective values を取得
855
855
  raw_objective_values = df[self.obj_names].values
856
- objective_values = np.full_like(raw_objective_values, np.nan)
856
+ objective_values = np.full_like(raw_objective_values, np.nan, dtype=float)
857
857
  for n_trial in range(len(raw_objective_values)):
858
858
  for obj_idx, (_, objective) in enumerate(objectives.items()):
859
859
  objective_values[n_trial, obj_idx] = objective.convert(raw_objective_values[n_trial, obj_idx])
@@ -25,7 +25,7 @@ from pyfemtet.opt.interface._surrogate._base import SurrogateModelInterfaceBase
25
25
  from pyfemtet.opt.interface._surrogate._singletaskgp import PoFBoTorchInterface
26
26
 
27
27
 
28
- __all__ =[
28
+ __all__ = [
29
29
  'FEMInterface',
30
30
  'NoFEM',
31
31
  'FemtetInterface',
@@ -24,18 +24,27 @@ class FEMInterface(ABC):
24
24
 
25
25
  """
26
26
 
27
+ kwargs = None
28
+
27
29
  def __init__(
28
30
  self,
29
31
  **kwargs
30
32
  ):
31
33
  # restore のための情報保管
32
- self.kwargs = kwargs
34
+ if self.kwargs is None:
35
+ self.kwargs = kwargs
36
+ else:
37
+ self.kwargs.update(kwargs)
33
38
 
34
39
  @abstractmethod
35
40
  def update(self, parameters: pd.DataFrame) -> None:
36
41
  """Updates the FEM analysis based on the proposed parameters."""
37
42
  raise NotImplementedError('update() must be implemented.')
38
43
 
44
+ @property
45
+ def object_passed_to_functions(self):
46
+ return self
47
+
39
48
  def check_param_value(self, param_name) -> float or None:
40
49
  """Checks the value of a parameter in the FEM model (if implemented in concrete class)."""
41
50
  pass
@@ -50,13 +59,13 @@ class FEMInterface(ABC):
50
59
  pass
51
60
 
52
61
  def load_parameter(self, opt) -> None: # opt: AbstractOptimizer
53
- raise NotImplementedError()
62
+ pass
54
63
 
55
64
  def load_objective(self, opt) -> None: # opt: AbstractOptimizer
56
- raise NotImplementedError()
65
+ pass
57
66
 
58
67
  def load_constraint(self, opt) -> None: # opt: AbstractOptimizer
59
- raise NotImplementedError()
68
+ pass
60
69
 
61
70
  def _setup_before_parallel(self, client) -> None:
62
71
  """Preprocessing before launching a dask worker (if implemented in concrete class).
@@ -55,36 +55,36 @@ class ExcelInterface(FEMInterface):
55
55
  input_xlsm_path (str or Path):
56
56
  設計変数の定義を含む Excel ファイルのパスを指定
57
57
  します。
58
-
58
+
59
59
  input_sheet_name (str):
60
60
  設計変数の定義を含むシートの名前を指定します。
61
-
61
+
62
62
  output_xlsm_path (str or Path, optional):
63
63
  目的関数の定義を含む Excel ファイルのパスを指定
64
64
  します。指定しない場合は ``input_xlsm_path`` と
65
65
  同じと見做します。
66
-
66
+
67
67
  output_sheet_name (str, optional):
68
68
  目的関数の定義を含む含むシートの名前を指定します。
69
69
  指定しない場合は ``input_sheet_name`` と同じと見
70
70
  做します。
71
-
71
+
72
72
  procedure_name (str, optional):
73
73
  Excel マクロ関数名を指定します。指定しない場合は
74
74
  ``FemtetMacro.FemtetMain`` と見做します。
75
-
75
+
76
76
  procedure_args (list or tuple, optional):
77
77
  Excel マクロ関数に渡す引数をリストまたはタプルで
78
78
  指定します。
79
-
79
+
80
80
  connect_method (str, optional):
81
81
  Excel との接続方法を指定します。 'auto' または
82
- 'new' が利用可能です。デフォルトは 'auto' です。
83
-
82
+ 'new' が利用可能です。デフォルトは 'new' です。
83
+
84
84
  procedure_timeout (float or None, optional):
85
85
  Excel マクロ関数のタイムアウト時間を秒単位で指定
86
86
  します。 None の場合はタイムアウトなしとなります。
87
-
87
+
88
88
  setup_xlsm_path (str or Path, optional):
89
89
  セットアップ時に呼ぶ関数を含む xlsm のパスです。
90
90
  指定しない場合は ``input_xlsm_path`` と
@@ -135,7 +135,7 @@ class ExcelInterface(FEMInterface):
135
135
  Attributes:
136
136
  input_xlsm_path (Path):
137
137
  設計変数の定義を含む Excel ファイルのパス。
138
-
138
+
139
139
  input_sheet_name (str):
140
140
  設計変数の定義を含むシートの名前。
141
141
 
@@ -232,7 +232,7 @@ class ExcelInterface(FEMInterface):
232
232
  constraint_sheet_name: str = None,
233
233
  procedure_name: str = None,
234
234
  procedure_args: list or tuple = None,
235
- connect_method: str = 'auto', # or 'new'
235
+ connect_method: str = 'new', # or 'auto'
236
236
  procedure_timeout: float or None = None,
237
237
  setup_xlsm_path: str or Path = None,
238
238
  setup_procedure_name: str = None,
@@ -257,7 +257,7 @@ class ExcelInterface(FEMInterface):
257
257
  self.output_sheet_name = output_sheet_name if output_sheet_name is not None else input_sheet_name
258
258
  self.constraint_xlsm_path = str(input_xlsm_path) if constraint_xlsm_path is None else str(constraint_xlsm_path)
259
259
  self.constraint_sheet_name = constraint_sheet_name or self.input_sheet_name
260
- self.procedure_name = procedure_name or 'FemtetMacro.FemtetMain'
260
+ self.procedure_name = procedure_name
261
261
  self.procedure_args = procedure_args or []
262
262
  assert connect_method in ['new', 'auto']
263
263
  self.connect_method = connect_method
@@ -271,7 +271,8 @@ class ExcelInterface(FEMInterface):
271
271
  self.setup_procedure_name = setup_procedure_name
272
272
  self.setup_procedure_args = setup_procedure_args or []
273
273
 
274
- self.teardown_xlsm_path = str(input_xlsm_path) if teardown_xlsm_path is None else str(teardown_xlsm_path) # あとで取得する
274
+ self.teardown_xlsm_path = str(input_xlsm_path) if teardown_xlsm_path is None else str(
275
+ teardown_xlsm_path) # あとで取得する
275
276
  self.teardown_procedure_name = teardown_procedure_name
276
277
  self.teardown_procedure_args = teardown_procedure_args or []
277
278
 
@@ -442,7 +443,7 @@ class ExcelInterface(FEMInterface):
442
443
  self.excel = DispatchEx('Excel.Application')
443
444
 
444
445
  # FemtetRef を追加する
445
- self.open_femtet_ref_xla() # ここでエラーが発生しているかも?
446
+ self.open_femtet_ref_xla()
446
447
  sleep(0.5)
447
448
 
448
449
  # 起動した excel の pid を記憶する
@@ -516,7 +517,8 @@ class ExcelInterface(FEMInterface):
516
517
  self.sh_constraint = sh
517
518
  break
518
519
  else:
519
- raise RuntimeError(f'Sheet {self.constraint_sheet_name} does not exist in the book {self.wb_constraint.Name}.')
520
+ raise RuntimeError(
521
+ f'Sheet {self.constraint_sheet_name} does not exist in the book {self.wb_constraint.Name}.')
520
522
 
521
523
  # ===== setup =====
522
524
  # 開く (setup)
@@ -618,18 +620,19 @@ class ExcelInterface(FEMInterface):
618
620
  self.update_parameter(parameters)
619
621
 
620
622
  # マクロ実行
621
- try:
622
- with watch_excel_macro_error(self.excel, timeout=self.procedure_timeout):
623
- self.excel.Run(
624
- f'{self.procedure_name}',
625
- *self.procedure_args
626
- )
623
+ if self.procedure_name is not None:
624
+ try:
625
+ with watch_excel_macro_error(self.excel, timeout=self.procedure_timeout):
626
+ self.excel.Run(
627
+ f'{self.procedure_name}',
628
+ *self.procedure_args
629
+ )
627
630
 
628
- # 再計算
629
- self.excel.CalculateFull()
631
+ # 再計算
632
+ self.excel.CalculateFull()
630
633
 
631
- except com_error as e:
632
- raise SolveError(f'Failed to run macro {self.procedure_name}. The original message is: {e}')
634
+ except com_error as e:
635
+ raise SolveError(f'Failed to run macro {self.procedure_name}. The original message is: {e}')
633
636
 
634
637
  def quit(self):
635
638
  if self.terminate_excel_when_quit:
@@ -655,7 +658,8 @@ class ExcelInterface(FEMInterface):
655
658
  self.excel.CalculateFull()
656
659
 
657
660
  except com_error as e:
658
- raise RuntimeError(f'Failed to run macro {self.teardown_procedure_args}. The original message is: {e}')
661
+ raise RuntimeError(
662
+ f'Failed to run macro {self.teardown_procedure_args}. The original message is: {e}')
659
663
 
660
664
  # 不具合の原因になる場合があるので参照設定は解除しないこと
661
665
  # self.remove_femtet_ref_xla(self.wb_input)
@@ -726,11 +730,15 @@ class ExcelInterface(FEMInterface):
726
730
  def input_workbook(self) -> CDispatch:
727
731
  return self.wb_input
728
732
 
729
- def load_parameter(self, opt) -> None:
733
+ def load_parameter(self, opt, raise_if_no_keyword=True) -> None:
730
734
  from pyfemtet.opt.optimizer import AbstractOptimizer, logger
731
735
  opt: AbstractOptimizer
732
736
 
733
- df = ParseAsParameter.parse(self.input_xlsm_path, self.input_sheet_name)
737
+ df = ParseAsParameter.parse(
738
+ self.input_xlsm_path,
739
+ self.input_sheet_name,
740
+ raise_if_no_keyword,
741
+ )
734
742
 
735
743
  for i, row in df.iterrows():
736
744
 
@@ -777,6 +785,7 @@ class ExcelInterface(FEMInterface):
777
785
  opt.variables.add_parameter(prm)
778
786
 
779
787
  else:
788
+ # noinspection PyTypeChecker
780
789
  fixed_prm = Expression(
781
790
  name=name,
782
791
  fun=lambda: value,
@@ -790,12 +799,16 @@ class ExcelInterface(FEMInterface):
790
799
  )
791
800
  opt.variables.add_expression(fixed_prm)
792
801
 
793
- def load_objective(self, opt):
794
- from pyfemtet.opt.optimizer import AbstractOptimizer, logger
802
+ def load_objective(self, opt, raise_if_no_keyword=True):
803
+ from pyfemtet.opt.optimizer import AbstractOptimizer
795
804
  from pyfemtet.opt._femopt_core import Objective
796
805
  opt: AbstractOptimizer
797
806
 
798
- df = ParseAsObjective.parse(self.output_xlsm_path, self.output_sheet_name)
807
+ df = ParseAsObjective.parse(
808
+ self.output_xlsm_path,
809
+ self.output_sheet_name,
810
+ raise_if_no_keyword,
811
+ )
799
812
 
800
813
  for i, row in df.iterrows():
801
814
 
@@ -827,22 +840,19 @@ class ExcelInterface(FEMInterface):
827
840
  kwargs=dict(),
828
841
  )
829
842
 
830
- def load_constraint(self, opt):
831
- from pyfemtet.opt.optimizer import AbstractOptimizer, logger
843
+ def load_constraint(self, opt, raise_if_no_keyword=False):
844
+ from pyfemtet.opt.optimizer import AbstractOptimizer
832
845
  from pyfemtet.opt._femopt_core import Constraint
833
846
  opt: AbstractOptimizer
834
847
 
835
- # TODO:
836
- # constraint optional である。
837
- # 現在は実装していないが、シートから問題を取得するよりよいロジックができたら
838
- # (つまり、同じシートからパラメータと拘束を取得出来るようになったら)__init__ 内で
839
- # constraint に None が与えられたのか故意に input_sheet_name と同じシート名を
840
- # 与えられたのか分別できる実装に変えてそのチェック処理をここに反映する。
841
- # constraint_sheet_name が指定されていない場合何もしない
842
- if (self.constraint_sheet_name == self.input_sheet_name) and is_same_path(self.input_xlsm_path, self.constraint_xlsm_path):
843
- return
844
-
845
- df = ParseAsConstraint.parse(self.constraint_xlsm_path, self.constraint_sheet_name)
848
+ # constraint は optional であるが
849
+ # __init__ input_sheet_name を入れられるので
850
+ # ここで constraint が実際に与えられているか判断する
851
+ df = ParseAsConstraint.parse(
852
+ self.constraint_xlsm_path,
853
+ self.constraint_sheet_name,
854
+ raise_if_no_keyword=raise_if_no_keyword,
855
+ )
846
856
 
847
857
  for i, row in df.iterrows():
848
858
 
@@ -877,7 +887,8 @@ class ExcelInterface(FEMInterface):
877
887
  calc_before_solve = True
878
888
  if ParseAsConstraint.calc_before_solve in df.columns:
879
889
  _calc_before_solve = row[ParseAsConstraint.calc_before_solve]
880
- calc_before_solve = True if is_cell_value_empty(_calc_before_solve) else bool(_calc_before_solve) # bool or NaN
890
+ calc_before_solve = True if is_cell_value_empty(_calc_before_solve) else bool(
891
+ _calc_before_solve) # bool or NaN
881
892
 
882
893
  if use:
883
894
  # constraint を作る
@@ -892,6 +903,7 @@ class ExcelInterface(FEMInterface):
892
903
  using_fem=not calc_before_solve,
893
904
  )
894
905
 
906
+ # TODO: femopt_core.Function の仕様を変えたらここも変える
895
907
  def objective_from_excel(self, name: str):
896
908
  r = 1 + search_r(self.output_xlsm_path, self.output_sheet_name, name)
897
909
  c = 1 + search_c(self.output_xlsm_path, self.output_sheet_name, ParseAsObjective.value)
@@ -192,7 +192,8 @@ class FemtetInterface(FEMInterface):
192
192
  # subprocess で restore するための情報保管
193
193
  # パスなどは connect_and_open_femtet での処理結果を反映し
194
194
  # メインで開いた解析モデルが確実に開かれるようにする
195
- super().__init__(
195
+ FEMInterface.__init__(
196
+ self,
196
197
  femprj_path=self.femprj_path,
197
198
  model_name=self.model_name,
198
199
  open_result_with_gui=self.open_result_with_gui,
@@ -201,6 +202,10 @@ class FemtetInterface(FEMInterface):
201
202
  **kwargs
202
203
  )
203
204
 
205
+ @property
206
+ def object_passed_to_functions(self):
207
+ return self.Femtet
208
+
204
209
  def use_parametric_output_as_objective(self, number: int, direction: str | float = 'minimize') -> None:
205
210
  """Use output setting of Femtet parametric analysis as an objective function.
206
211
 
@@ -234,7 +239,6 @@ class FemtetInterface(FEMInterface):
234
239
  self.kwargs['parametric_output_indexes_use_as_objective'] = self.parametric_output_indexes_use_as_objective
235
240
 
236
241
 
237
-
238
242
  def __del__(self):
239
243
  self.quit()
240
244
  # CoUninitialize() # Win32 exception occurred releasing IUnknown at 0x0000022427692748
@@ -0,0 +1,141 @@
1
+ import re
2
+ from pathlib import Path
3
+
4
+ from pyfemtet.opt.interface._base import FEMInterface
5
+ from pyfemtet.opt.interface._femtet import FemtetInterface
6
+ from pyfemtet.opt.interface._excel_interface import (
7
+ ExcelInterface, is_cell_value_empty, ParseAsObjective, ScapeGoatObjective,
8
+ ParseAsConstraint, search_c, search_r
9
+ )
10
+
11
+
12
+ PARAMETRIC_PREFIX = 'パラメトリック'
13
+
14
+
15
+ def get_number(name):
16
+ numbers = re.findall(r'\d+', name)
17
+ if len(numbers) == 0:
18
+ raise ValueError('パラメトリック結果出力の番号指定が検出できませんでした。')
19
+ else:
20
+ return int(numbers[0])
21
+
22
+
23
+
24
+ class FemtetWithExcelSettingsInterface(FemtetInterface, ExcelInterface, FEMInterface):
25
+
26
+ def __init__(
27
+ self,
28
+
29
+ # FemtetInterface arguments
30
+ femprj_path: str = None, model_name: str = None, connect_method: str = 'auto',
31
+ save_pdt: str = 'all', strictly_pid_specify: bool = True, allow_without_project: bool = False,
32
+ open_result_with_gui: bool = True,
33
+ parametric_output_indexes_use_as_objective: dict[int, str or float] = None,
34
+
35
+ # ExcelInterface arguments
36
+ input_xlsm_path: str or Path = None, input_sheet_name: str = None, output_xlsm_path: str or Path = None,
37
+ output_sheet_name: str = None, constraint_xlsm_path: str or Path = None,
38
+ constraint_sheet_name: str = None, procedure_name: str = None, procedure_args: list or tuple = None,
39
+ procedure_timeout: float or None = None,
40
+ setup_xlsm_path: str or Path = None, setup_procedure_name: str = None,
41
+ setup_procedure_args: list or tuple = None, teardown_xlsm_path: str or Path = None,
42
+ teardown_procedure_name: str = None, teardown_procedure_args: list or tuple = None,
43
+ related_file_paths: list[str or Path] = None, visible: bool = False, display_alerts: bool = False,
44
+ terminate_excel_when_quit: bool = None, interactive: bool = True, use_named_range: bool = True,
45
+
46
+ ):
47
+
48
+ excel_connect_method = 'new'
49
+
50
+ ExcelInterface.__init__(
51
+ self, input_xlsm_path, input_sheet_name, output_xlsm_path, output_sheet_name, constraint_xlsm_path,
52
+ constraint_sheet_name, procedure_name, procedure_args, excel_connect_method, procedure_timeout,
53
+ setup_xlsm_path, setup_procedure_name, setup_procedure_args, teardown_xlsm_path,
54
+ teardown_procedure_name, teardown_procedure_args, related_file_paths, visible, display_alerts,
55
+ terminate_excel_when_quit, interactive, use_named_range)
56
+
57
+ FemtetInterface.__init__(
58
+ self,
59
+ femprj_path, model_name, connect_method, save_pdt, strictly_pid_specify, allow_without_project,
60
+ open_result_with_gui, parametric_output_indexes_use_as_objective
61
+ )
62
+
63
+
64
+ def load_objective(self, opt, raise_if_no_keyword=True):
65
+ from pyfemtet.opt.optimizer import AbstractOptimizer
66
+ from pyfemtet.opt._femopt_core import Objective
67
+ opt: AbstractOptimizer
68
+
69
+ df = ParseAsObjective.parse(
70
+ self.output_xlsm_path,
71
+ self.output_sheet_name,
72
+ raise_if_no_keyword,
73
+ )
74
+
75
+ for i, row in df.iterrows():
76
+
77
+ # use(optional)
78
+ use = True
79
+ if ParseAsObjective.use in df.columns:
80
+ _use = row[ParseAsObjective.use]
81
+ use = False if is_cell_value_empty(_use) else bool(_use) # bool or NaN
82
+
83
+ # name
84
+ name = str(row[ParseAsObjective.name])
85
+
86
+ # direction
87
+ direction = row[ParseAsObjective.direction]
88
+ assert not is_cell_value_empty(direction), 'direction is empty.'
89
+ try:
90
+ direction = float(direction)
91
+ except ValueError:
92
+ direction = str(direction).lower()
93
+ assert direction in ['minimize', 'maximize']
94
+
95
+ if use:
96
+
97
+ # name が「パラメトリック」から始まっていたら
98
+ # パラメトリック解析の結果を目的関数にする
99
+ if name.startswith(PARAMETRIC_PREFIX):
100
+ number = get_number(name)
101
+ self.use_parametric_output_as_objective(number, direction)
102
+
103
+ # そうでなければ通常の Excel objective を作る
104
+ else:
105
+ opt.objectives[name] = Objective(
106
+ fun=ScapeGoatObjective(),
107
+ name=name,
108
+ direction=direction,
109
+ args=(name,),
110
+ kwargs=dict(),
111
+ )
112
+
113
+ def _setup_before_parallel(self, client):
114
+ FemtetInterface._setup_before_parallel(self, client)
115
+ ExcelInterface._setup_before_parallel(self, client)
116
+
117
+ def _setup_after_parallel(self, *args, **kwargs):
118
+ FemtetInterface._setup_after_parallel(self, *args, **kwargs)
119
+ ExcelInterface._setup_after_parallel(self, *args, **kwargs)
120
+
121
+ def update(self, parameters) -> None:
122
+ FemtetInterface.update(self, parameters)
123
+ ExcelInterface.update(self, parameters)
124
+
125
+ def quit(self, timeout=1, force=True):
126
+ FemtetInterface.quit(self, timeout, force)
127
+ ExcelInterface.quit(self)
128
+
129
+ # noinspection PyMethodOverriding
130
+ def objective_from_excel(self, _, name: str):
131
+ r = 1 + search_r(self.output_xlsm_path, self.output_sheet_name, name)
132
+ c = 1 + search_c(self.output_xlsm_path, self.output_sheet_name, ParseAsObjective.value)
133
+ v = self.sh_output.Cells(r, c).value
134
+ return float(v)
135
+
136
+ # noinspection PyMethodOverriding
137
+ def constraint_from_excel(self, _, name: str):
138
+ r = 1 + search_r(self.constraint_xlsm_path, self.constraint_sheet_name, name)
139
+ c = 1 + search_c(self.constraint_xlsm_path, self.constraint_sheet_name, ParseAsConstraint.value)
140
+ v = self.sh_constraint.Cells(r, c).value
141
+ return float(v)
@@ -107,7 +107,8 @@ class ParametricResultCSVProcessor:
107
107
 
108
108
  # 与えられた output_number に関連する行だけ抜き出し
109
109
  # エラーがあるかどうかチェックする
110
- pdf = df['結果出力設定番号'] == parametric_output_index + 1
110
+ idx = df['結果出力設定番号'] == parametric_output_index + 1
111
+ pdf = df[idx]
111
112
 
112
113
  # 結果出力設定番号 カラムが存在しない
113
114
  else:
@@ -17,6 +17,7 @@ class SurrogateModelInterfaceBase(FEMInterface, ABC):
17
17
  self,
18
18
  history_path: str = None,
19
19
  train_history: History = None,
20
+ _output_directions: dict[int, str | float] | list[str | float] = None,
20
21
  ):
21
22
 
22
23
  self.train_history: History
@@ -25,6 +26,7 @@ class SurrogateModelInterfaceBase(FEMInterface, ABC):
25
26
  self.obj: dict[str, float] = dict()
26
27
  self.df_prm: pd.DataFrame
27
28
  self.df_obj: pd.DataFrame
29
+ self._output_directions = _output_directions
28
30
 
29
31
  # history_path が与えられた場合、train_history をコンストラクトする
30
32
  if history_path is not None:
@@ -54,11 +56,52 @@ class SurrogateModelInterfaceBase(FEMInterface, ABC):
54
56
  self.df_prm = df_prm
55
57
  self.df_obj = df_obj
56
58
 
59
+ # _output_directions が与えられている場合、
60
+ # history から objective の設定を読み込む
61
+ if self._output_directions is not None:
62
+ self._load_problem_from_me: bool = True
63
+
57
64
  FEMInterface.__init__(
58
65
  self,
59
66
  train_history=train_history, # コンストラクト済み train_history を渡せば並列計算時も何もしなくてよい
60
67
  )
61
68
 
69
+
70
+ def load_objective(self, opt) -> None:
71
+ from pyfemtet.opt._femopt_core import Objective
72
+
73
+ assert self._output_directions is not None
74
+
75
+ if isinstance(self._output_directions, dict):
76
+
77
+ for index, direction in self._output_directions:
78
+ obj_name = self.train_history.obj_names[index]
79
+ opt.objectives[obj_name] = Objective(
80
+ lambda obj_name_=obj_name: self.obj[obj_name_],
81
+ name=obj_name,
82
+ direction=direction,
83
+ args=(),
84
+ kwargs={},
85
+ )
86
+
87
+ elif isinstance(self._output_directions, list) \
88
+ or isinstance(self._output_directions, tuple):
89
+
90
+ obj_names = self.train_history.obj_names
91
+ assert len(self._output_directions) == len(obj_names)
92
+
93
+ for obj_name, direction in zip(obj_names, self._output_directions):
94
+ opt.objectives[obj_name] = Objective(
95
+ lambda obj_name_=obj_name: self.obj[obj_name_],
96
+ name=obj_name,
97
+ direction=direction,
98
+ args=(),
99
+ kwargs={},
100
+ )
101
+
102
+ else:
103
+ raise ValueError('Invalid _output_directions')
104
+
62
105
  def filter_feasible(self, x: np.ndarray, y: np.ndarray, return_feasibility=False):
63
106
  feasible_idx = np.where(~np.isnan(y.sum(axis=1)))
64
107
  if return_feasibility:
@@ -0,0 +1,102 @@
1
+ import re
2
+ from pathlib import Path
3
+
4
+ from pyfemtet.opt._femopt_core import History
5
+ from pyfemtet.opt.interface._base import FEMInterface
6
+ from pyfemtet.opt.interface._surrogate._singletaskgp import PoFBoTorchInterface
7
+ from pyfemtet.opt.interface._excel_interface import ExcelInterface
8
+
9
+
10
+ class PoFBoTorchInterfaceWithExcelSettingsInterface(
11
+ PoFBoTorchInterface,
12
+ ExcelInterface,
13
+ FEMInterface,
14
+ ):
15
+
16
+ def __init__(
17
+ self,
18
+
19
+ # SurrogateModel
20
+ history_path: str = None, train_history: History = None,
21
+
22
+ # Excel
23
+ input_xlsm_path: str or Path = None,
24
+ input_sheet_name: str = None,
25
+ output_xlsm_path: str or Path = None,
26
+ output_sheet_name: str = None,
27
+ constraint_xlsm_path: str or Path = None,
28
+ constraint_sheet_name: str = None,
29
+ procedure_name: str = None,
30
+ procedure_args: list or tuple = None,
31
+ # connect_method: str = 'auto', # or 'new'
32
+ procedure_timeout: float or None = None,
33
+ setup_xlsm_path: str or Path = None,
34
+ setup_procedure_name: str = None,
35
+ setup_procedure_args: list or tuple = None,
36
+ teardown_xlsm_path: str or Path = None,
37
+ teardown_procedure_name: str = None,
38
+ teardown_procedure_args: list or tuple = None,
39
+ related_file_paths: list[str or Path] = None,
40
+ visible: bool = False,
41
+ display_alerts: bool = False,
42
+ terminate_excel_when_quit: bool = None,
43
+ interactive: bool = True,
44
+ use_named_range: bool = True,
45
+ ):
46
+ PoFBoTorchInterface.__init__(
47
+ self,
48
+ history_path,
49
+ train_history,
50
+ )
51
+
52
+ connect_method = 'new'
53
+
54
+ ExcelInterface.__init__(
55
+ self,
56
+ input_xlsm_path,
57
+ input_sheet_name,
58
+ output_xlsm_path,
59
+ output_sheet_name,
60
+ constraint_xlsm_path,
61
+ constraint_sheet_name,
62
+ procedure_name,
63
+ procedure_args,
64
+ connect_method, # or 'new'
65
+ procedure_timeout,
66
+ setup_xlsm_path,
67
+ setup_procedure_name,
68
+ setup_procedure_args,
69
+ teardown_xlsm_path,
70
+ teardown_procedure_name,
71
+ teardown_procedure_args,
72
+ related_file_paths,
73
+ visible,
74
+ display_alerts,
75
+ terminate_excel_when_quit,
76
+ interactive,
77
+ use_named_range,
78
+ )
79
+
80
+ def load_parameter(self, opt, raise_if_no_keyword=True) -> None:
81
+ ExcelInterface.load_parameter(self, opt, raise_if_no_keyword)
82
+
83
+ def load_objective(self, opt, raise_if_no_keyword=True) -> None:
84
+ ExcelInterface.load_objective(self, opt, raise_if_no_keyword)
85
+
86
+ def load_constraint(self, opt, raise_if_no_keyword=False):
87
+ ExcelInterface.load_constraint(self, opt, raise_if_no_keyword)
88
+
89
+ def _setup_before_parallel(self, client):
90
+ PoFBoTorchInterface._setup_before_parallel(self, client)
91
+ ExcelInterface._setup_before_parallel(self, client)
92
+
93
+ def _setup_after_parallel(self, *args, **kwargs):
94
+ PoFBoTorchInterface._setup_after_parallel(self, *args, **kwargs)
95
+ ExcelInterface._setup_after_parallel(self, *args, **kwargs)
96
+
97
+ def update(self, parameters) -> None:
98
+ PoFBoTorchInterface.update(self, parameters)
99
+
100
+ def quit(self):
101
+ PoFBoTorchInterface.quit(self)
102
+ ExcelInterface.quit(self)
File without changes
@@ -0,0 +1,213 @@
1
+ CONFIRM_BEFORE_ABNORMAL_TERMINATION = True
2
+
3
+ try:
4
+
5
+ # for meta script
6
+ import os
7
+ import sys
8
+ import importlib
9
+ import pyfemtet
10
+
11
+ if __name__ == '__main__':
12
+ print(f'pyfemtet {pyfemtet.__version__} starting.')
13
+
14
+ from pyfemtet._message.messages import encoding
15
+
16
+ from fire import Fire
17
+ import yaml
18
+
19
+ # for concrete script
20
+ from optuna.samplers import *
21
+ from pyfemtet.opt import FEMOpt
22
+ from pyfemtet.opt.interface import *
23
+ from pyfemtet.opt.optimizer import *
24
+ from pyfemtet.opt.interface._femtet_excel import FemtetWithExcelSettingsInterface
25
+ from pyfemtet.opt.interface._surrogate_excel import PoFBoTorchInterfaceWithExcelSettingsInterface
26
+
27
+ # for debug
28
+ DEBUG = False
29
+
30
+ class ContentContext:
31
+
32
+ def __init__(self, content_):
33
+ self.content = content_
34
+
35
+ def __enter__(self):
36
+ return self.content
37
+
38
+ def __exit__(self, exc_type, exc_val, exc_tb):
39
+ pass
40
+
41
+ # for importing user-defined module
42
+ def import_from_path(module_name, file_path):
43
+
44
+ print(f'{file_path=}')
45
+
46
+ # noinspection PyUnresolvedReferences
47
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
48
+
49
+ print(f'{spec=}')
50
+
51
+ # noinspection PyUnresolvedReferences
52
+ module = importlib.util.module_from_spec(spec)
53
+
54
+ print(f'{module=}')
55
+
56
+ sys.modules[module_name] = module
57
+ spec.loader.exec_module(module)
58
+ return module
59
+
60
+
61
+ def main(
62
+ yaml_path: str = None,
63
+
64
+ interface_class: str = None, # including parameter definition excel
65
+ interface_kwargs: str = None, # including Parametric Analysis Output
66
+ optimizer_class: str = None,
67
+ optimizer_kwargs: str = None,
68
+ femopt_kwargs: str = None,
69
+ seed: str = 'null',
70
+ optimize_kwargs: str = None,
71
+ additional_module_paths: list[str] = None,
72
+
73
+ confirm_before_abnormal_termination: bool = True,
74
+ ):
75
+ """
76
+
77
+ Args:
78
+ yaml_path:
79
+ If this argument is passed, the other arguments will be ignored
80
+ and load by .yaml file.
81
+ The yaml file must contain the other arguments.
82
+
83
+ interface_class: FemtetWithExcelSettingsInterface or SurrogateModelInterface.
84
+ interface_kwargs: See documentation of each interface class.
85
+ optimizer_class: OptunaOptimizer or ScipyOptimizer.
86
+ optimizer_kwargs: See documentation of each optimizer class.
87
+ femopt_kwargs: See documentation of FEMOpt.
88
+ seed: int or None.
89
+ optimize_kwargs: See documentation of FEMOpt.optimize().
90
+ additional_module_paths:
91
+ The .py file paths containing user-defined objective and constraints functions.
92
+ The module must contain __objective_functions__ or __constraint_functions__.
93
+ They must be a dict variable that contains the required arguments of
94
+ `FEMOpt.add_objective()` or `FEMOpt.add_constraint()` method.
95
+ Note that the `args` argument of constraint function is reserved by meta_script
96
+ and that value is fixed to `FEMOpt.opt`, so you can not use `args` argument
97
+ in __constraint_functions__.
98
+ Note that the functions should not contain the python variables defined outside
99
+ global scope.
100
+ confirm_before_abnormal_termination: Pause before termination if an error occurs. Default is True.
101
+
102
+ """
103
+
104
+ global CONFIRM_BEFORE_ABNORMAL_TERMINATION
105
+ CONFIRM_BEFORE_ABNORMAL_TERMINATION = confirm_before_abnormal_termination
106
+
107
+ # load variables from yaml file
108
+ if yaml_path is not None:
109
+
110
+ # check
111
+ if os.path.isfile(yaml_path):
112
+ context = open(yaml_path, 'r', encoding='utf-8')
113
+
114
+ else:
115
+ if DEBUG:
116
+ print('debug mode')
117
+ context = ContentContext(yaml_path) # yaml_path is yaml content
118
+
119
+ else:
120
+ raise FileNotFoundError(yaml_path)
121
+
122
+ # load **as yaml content**
123
+ with context as f:
124
+ d = yaml.safe_load(f)
125
+ interface_class = yaml.safe_dump(d['interface_class'], allow_unicode=True)
126
+ interface_kwargs = yaml.safe_dump(d['interface_kwargs'], allow_unicode=True)
127
+ optimizer_class = yaml.safe_dump(d['optimizer_class'], allow_unicode=True)
128
+ optimizer_kwargs = yaml.safe_dump(d['optimizer_kwargs'], allow_unicode=True)
129
+ femopt_kwargs = yaml.safe_dump(d['femopt_kwargs'], allow_unicode=True)
130
+ seed = yaml.safe_dump(d['seed'], allow_unicode=True)
131
+ optimize_kwargs = yaml.safe_dump(d['optimize_kwargs'], allow_unicode=True)
132
+ additional_module_paths = yaml.safe_dump(d.get('additional_module_paths', None), allow_unicode=True)
133
+
134
+ # load **python variables** from yaml content
135
+
136
+ # additional import
137
+ additional_module_paths_ = yaml.safe_load(additional_module_paths)
138
+
139
+ if additional_module_paths_ is not None:
140
+
141
+ for i, path_ in enumerate(additional_module_paths_):
142
+
143
+ # noinspection PyUnresolvedReferences
144
+ additional_module = import_from_path(f'additional_module_{i}', path_)
145
+
146
+ # from additional_module import *
147
+ if hasattr(additional_module, '__all__'):
148
+ globals().update({key: getattr(additional_module, key) for key in additional_module.__all__})
149
+
150
+ Interface = eval(yaml.safe_load(interface_class))
151
+ interface_kwargs_ = yaml.safe_load(interface_kwargs)
152
+
153
+ Optimizer = eval(yaml.safe_load(optimizer_class))
154
+ optimizer_kwargs_ = yaml.safe_load(optimizer_kwargs)
155
+
156
+ optimizer_kwargs_['sampler_class'] = eval(optimizer_kwargs_['sampler_class'])
157
+
158
+ femopt_kwargs_ = yaml.safe_load(femopt_kwargs)
159
+
160
+ seed_ = yaml.safe_load(seed)
161
+
162
+ optimize_kwargs_ = yaml.safe_load(optimize_kwargs)
163
+
164
+ fem = Interface(**interface_kwargs_)
165
+ opt = Optimizer(**optimizer_kwargs_)
166
+ femopt = FEMOpt(fem=fem, opt=opt, **femopt_kwargs_)
167
+
168
+ if additional_module_paths_ is not None:
169
+
170
+ for i, path_ in enumerate(additional_module_paths_):
171
+
172
+ # noinspection PyUnresolvedReferences
173
+ additional_module = import_from_path(f'additional_module_{i}', path_)
174
+
175
+ # import obj & cns
176
+ d: dict
177
+ if hasattr(additional_module, '__objective_functions__'):
178
+ for d in additional_module.__objective_functions__:
179
+ femopt.add_objective(
180
+ fun=d['fun'],
181
+ name=d.get('name'),
182
+ direction=d.get('direction'),
183
+ args=d.get('args'),
184
+ kwargs=d.get('kwargs'),
185
+ )
186
+ if hasattr(additional_module, '__constraint_functions__'):
187
+ for d in additional_module.__constraint_functions__:
188
+ femopt.add_constraint(
189
+ fun=d['fun'],
190
+ name=d.get('name'),
191
+ lower_bound=d.get('lower_bound'),
192
+ upper_bound=d.get('upper_bound'),
193
+ strict=d.get('strict', True),
194
+ using_fem=d.get('using_fem'),
195
+ args=(femopt.opt,),
196
+ kwargs=d.get('kwargs'),
197
+ )
198
+
199
+ femopt.set_random_seed(seed_)
200
+ femopt.optimize(**optimize_kwargs_)
201
+
202
+
203
+ if __name__ == '__main__':
204
+ Fire(main)
205
+
206
+
207
+ except Exception as e:
208
+ from traceback import print_exception
209
+
210
+ print_exception(e)
211
+ print()
212
+ if CONFIRM_BEFORE_ABNORMAL_TERMINATION:
213
+ input('終了するには Enter を押してください。')
@@ -362,6 +362,19 @@ class OptunaVisualizerPage(AbstractPage):
362
362
  )
363
363
  layout.append(dcc.Graph(figure=fig, style={'height': '70vh'}))
364
364
 
365
+ layout.append(html.H2(Msg.DETAIL_PAGE_IMPORTANCE_HEADER))
366
+ layout.append(html.H4(Msg.DETAIL_PAGE_IMPORTANCE_DESCRIPTION))
367
+ for i, obj_name in enumerate(obj_names):
368
+ fig = optuna.visualization.plot_param_importances(
369
+ study,
370
+ target=lambda t: t.values[i],
371
+ target_name=obj_name
372
+ )
373
+ import plotly.graph_objects as go
374
+ fig: go.Figure
375
+ fig.update_layout(title=obj_name)
376
+ layout.append(dcc.Graph(figure=fig, style={'height': '70vh'}))
377
+
365
378
  return layout
366
379
 
367
380
  def setup_callback(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyfemtet
3
- Version: 0.8.9
3
+ Version: 0.8.11
4
4
  Summary: Design parameter optimization using Femtet.
5
5
  License: BSD-3-Clause
6
6
  Author: kazuma.naito
@@ -30,6 +30,7 @@ Requires-Dist: pandas (>=2.2.3,<3.0.0)
30
30
  Requires-Dist: plotly (>=5.22.0,<6.0.0)
31
31
  Requires-Dist: psutil (>=5.9.6,<6.0.0)
32
32
  Requires-Dist: pywin32 (>=306,<307) ; sys_platform == "win32"
33
+ Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
33
34
  Requires-Dist: scipy (>=1.11.4,<2.0.0)
34
35
  Requires-Dist: torch (>=2.5.1,<2.6.0) ; sys_platform != "linux"
35
36
  Requires-Dist: torch (>=2.5.1,<2.6.0) ; sys_platform == "linux"
@@ -1,4 +1,4 @@
1
- pyfemtet/__init__.py,sha256=jBrmFTf-nNFPcJTuyxzw1H9WEW7G7OpCejEb8xk5m-U,21
1
+ pyfemtet/__init__.py,sha256=2JL5Qr1tMuuX9W0K2n-UaciQXJtKIEm_9ijSZ2wv2C0,22
2
2
  pyfemtet/_femtet_config_util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  pyfemtet/_femtet_config_util/autosave.py,sha256=dNirA9XGuFehas8_Jkj2BW9GOzMbPyhnt1WHcH_ObSU,2070
4
4
  pyfemtet/_femtet_config_util/exit.py,sha256=0BWID-tjOkmZwmgPFkcJMkWW39voccz5ARIBWvZbHaw,1877
@@ -6,14 +6,14 @@ pyfemtet/_message/1. make_pot.bat,sha256=wrTA0YaL7nUfNB0cS8zljOmwq2qgyG6RMwHQbrw
6
6
  pyfemtet/_message/2. make_mo.bat,sha256=6shJ3Yn4BXjDc0hhv_kiGUtVTq4oSRz8-iS4vW29rNE,155
7
7
  pyfemtet/_message/__init__.py,sha256=gE1-XX_PzHj9BbhqPaK5VcIHuv6_Tec5qlPMC3IRiBg,100
8
8
  pyfemtet/_message/babel.cfg,sha256=AQIFCQ7NlAA84PhV0gowHhbIXH41zA55mzhgyROniJk,73
9
- pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo,sha256=Af0m1bHsrMAjqyfLlDjW_OK09IXnuDvByaESf7BvuQU,18984
10
- pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po,sha256=CPVryK95GFl_GSSTz1uSvkKwXaYRvTboIr_aTgdfwbo,25441
11
- pyfemtet/_message/locales/messages.pot,sha256=AxtocHuEX5VPgXgULpHBxU8swNLUzm9KEBbSP1Y6qP8,15017
12
- pyfemtet/_message/messages.py,sha256=OsSXVLn9_YKwuHczW1A4CEnhZ0wrtHmOhxPA9OPOzHc,13856
9
+ pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo,sha256=BsDrPmXWzKfaAjATSq-GZexNX4iG8ax7Ss0bfB1ocIk,19512
10
+ pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po,sha256=_ugJcUf__C1HdXt3ubcPurLQWKuL3dg0DGMcrDtTBbw,26047
11
+ pyfemtet/_message/locales/messages.pot,sha256=G_6aRv0zZjpShKx13hm_1B2D60sViOuUHpZsX5QJSpQ,15372
12
+ pyfemtet/_message/messages.py,sha256=ztDyORp0sjgNCe2DKEh-ojWfcVnVmOy3mEtAUt_yYhA,14185
13
13
  pyfemtet/_util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  pyfemtet/_util/dask_util.py,sha256=ufgr4m8slvyWP97lWBwolysQpJ1PmAO_-OI8IlEyvU8,233
15
15
  pyfemtet/_util/excel_macro_util.py,sha256=cF1Z3yl9FMM0J7dpMRTsle8uYxYcfHhQC0QffnVovdY,7944
16
- pyfemtet/_util/excel_parse_util.py,sha256=-puddKHcdf9OOWNXXeeUIuetAQ-wOepYdr37VdOqQf8,4148
16
+ pyfemtet/_util/excel_parse_util.py,sha256=AoVMTcjSm5PEytK5AdDTXZ4Gbj3V5KTlj0KfrN1ZzkU,4809
17
17
  pyfemtet/_util/sample.xlsx,sha256=OU8mBY48YESJFQrdt4OkntlE1z-6WiyUyOV-PMr09DQ,9423
18
18
  pyfemtet/_warning.py,sha256=TSOj8mOhuyfOUJB24LsW6GNhTA3IzIEevJw_hLKTrq8,2205
19
19
  pyfemtet/brep/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -24,14 +24,14 @@ pyfemtet/dispatch_extensions/_impl.py,sha256=yH_yeAnQ-Xi9GfjX-FQt9u3yHnrLYIteRb6
24
24
  pyfemtet/logger/__init__.py,sha256=UOJ9n_U2xwdTrp0Xgg-N6geySxNzKqTBQlXsaH0kW_w,420
25
25
  pyfemtet/logger/_impl.py,sha256=rsAd0HpmveOaLS39ucp3U2OcDhQMWjC5fnVGhbJtWVw,6375
26
26
  pyfemtet/opt/__init__.py,sha256=wRR8LbEhb5I6MUgmnCgjB6-tqHlOVxDIo7yPkq0QbBs,758
27
- pyfemtet/opt/_femopt.py,sha256=9-naHBWBVCd2jkIldhO_whrOh6AmpQLXUsdzyYKZyco,40587
28
- pyfemtet/opt/_femopt_core.py,sha256=hMnb5UD7R_FfF6VvNLakJedIdjv7B3i--nsvqhdue2M,39328
27
+ pyfemtet/opt/_femopt.py,sha256=MSqSJzyD2sRYBNQAe0P5rpSvvVihOV2ugUa-hZyYnBA,40671
28
+ pyfemtet/opt/_femopt_core.py,sha256=w8jcKAIxakO2JMC51TTWI3iL-3wlEg6wCDn45D4ZCe4,39366
29
29
  pyfemtet/opt/_test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  pyfemtet/opt/_test_utils/control_femtet.py,sha256=8oAl9y5V2n8Nnsgx_ebcZVzwFt1eI3swkdiKg6pg3-M,1085
31
31
  pyfemtet/opt/_test_utils/hyper_sphere.py,sha256=nQhw8EIY0DwvcTqrbKhkxiITLZifr4-nG77E-_6ggmA,700
32
32
  pyfemtet/opt/_test_utils/record_history.py,sha256=7V2LCZ8F985c_NNUVu-K7_2-p2mwG1lRMZhkYhSy_Dw,4356
33
33
  pyfemtet/opt/advanced_samples/excel_ui/(ref) original_project.femprj,sha256=5OqZfynTpVCrgEIOBOMYuDGaMvepi5lojVNFr1jAsEI,157489
34
- pyfemtet/opt/advanced_samples/excel_ui/femtet-macro.xlsm,sha256=ckF0SQ0f3IWSW6QoH1IPJdwUUlR7O_AiGC5fi8SI3jA,133137
34
+ pyfemtet/opt/advanced_samples/excel_ui/femtet-macro.xlsm,sha256=7G9hr1Oj1zwTFv6mh2fWk4FZ0R5ZNDQmvjNvujy6gbw,124145
35
35
  pyfemtet/opt/advanced_samples/excel_ui/pyfemtet-core.py,sha256=aF2TWXdbt7dnkeBqqVO6GvIExozjFp0mxx3BX8rpYNc,9879
36
36
  pyfemtet/opt/advanced_samples/excel_ui/test-pyfemtet-core.cmd,sha256=r-Pa1Ng9sa6wfDqIhTf2BUDrN9rePWFymz7pmtBbvcQ,895
37
37
  pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric.femprj,sha256=iIHH1X-wWBqEYj4cFJXco73LCJXSrYBsSKOD0HxYu60,87599
@@ -42,19 +42,24 @@ pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data_jp.p
42
42
  pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate.py,sha256=s0b31wuN3iXjb78dt0ro0ZjxHa8uLIH94jRfEuj1EVY,3090
43
43
  pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate_jp.py,sha256=OAOpHKyMMo1StSqNMqx4saYDn4hiGOKDypyK6uhTILQ,3215
44
44
  pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_parametric.femprj,sha256=iIHH1X-wWBqEYj4cFJXco73LCJXSrYBsSKOD0HxYu60,87599
45
- pyfemtet/opt/interface/__init__.py,sha256=na6-elI9-karOqoSxT9LfLQpjBPm1lrUWjow0NYYRP4,1349
46
- pyfemtet/opt/interface/_base.py,sha256=y0uQ5jdsWbgt5odyqPin7NXcK_IbUwPDcrrkV_JhpRw,2722
47
- pyfemtet/opt/interface/_excel_interface.py,sha256=s103vePTPXXYiPwGdAEUFgtpvGXtu1nSljDtP4HsmcY,40355
48
- pyfemtet/opt/interface/_femtet.py,sha256=_T75D0GWEYc_5n9RRF6u-HZVxgFnG9PoGYF2-cDiqeM,37673
49
- pyfemtet/opt/interface/_femtet_parametric.py,sha256=rhvnpHdbjNJAKxiCkgnExnZdV5qOB6pBv6AaLeTkeF8,10155
45
+ pyfemtet/opt/interface/__init__.py,sha256=SstCN9WMYqF5lKNbb8xAzq0hBV-Hk8YuCrajvF3sOg0,1350
46
+ pyfemtet/opt/interface/_base.py,sha256=zbRhNB4fwznKHsllC1X29TONoB9MP8qMH8Nqz4NX_yA,2838
47
+ pyfemtet/opt/interface/_excel_interface.py,sha256=1PYB056rU2mX-LgBWRwwTUxDkt7crgHAk3fKJuMNMMU,40152
48
+ pyfemtet/opt/interface/_femtet.py,sha256=bAeFG4oik0zt3PcbPOhhQOm0-kboS83JKn0RX_mIrP0,37779
49
+ pyfemtet/opt/interface/_femtet_excel.py,sha256=dWPQguKNOVdJ4jTfwLykCeM9iwA2S1KOLynw8UGzmvk,5968
50
+ pyfemtet/opt/interface/_femtet_parametric.py,sha256=hxNiZfhR1IPtrMXg39TZutXTcOXdoxTKiRTTcYRGgVs,10181
50
51
  pyfemtet/opt/interface/_femtet_with_nx/__init__.py,sha256=-6W2g2FDEcKzGHmI5KAKQe-4U5jDpMj0CXuma-GZca0,83
51
52
  pyfemtet/opt/interface/_femtet_with_nx/_interface.py,sha256=LkaODUSpBLq05uz5Jf-JKuH6Evq8ElZoItXxFZopWeM,5994
52
53
  pyfemtet/opt/interface/_femtet_with_nx/update_model.py,sha256=P7VH0i_o-X9OUe6AGaLF1fACPeHNrMjcrOBCA3MMrI4,3092
53
54
  pyfemtet/opt/interface/_femtet_with_sldworks.py,sha256=rjEgebuP1w1eAFVWw4eRJUq3lsyBcmXlkMjZKIpD0kw,11019
54
55
  pyfemtet/opt/interface/_surrogate/__init__.py,sha256=2UT5NuBylyWQJNjg1zsBRCV-MzNCUswTUt6ZuSrYFUM,120
55
- pyfemtet/opt/interface/_surrogate/_base.py,sha256=_mVjoxrGEWL-PydjzEYXIgsOJ9zPmntoRHY3dXR2HGo,3098
56
+ pyfemtet/opt/interface/_surrogate/_base.py,sha256=s_Mqo7CUAhaj-ZYYxxGKekiox4EnH_SnWB8eVj-VnFU,4739
56
57
  pyfemtet/opt/interface/_surrogate/_chaospy.py,sha256=Bqej89Mo0zgdJq1OK7YKRqHOcuyN0wL4ZQUQXdJtYJ8,1987
57
58
  pyfemtet/opt/interface/_surrogate/_singletaskgp.py,sha256=bHzY5QIjA9zhLxweexz259XQMZLgkHWfrIDW7f3q-2k,2520
59
+ pyfemtet/opt/interface/_surrogate_excel.py,sha256=r0i9xNb6R-1SHL911Pi9x6lD4mQbCl8m3cQG2dQft1E,3509
60
+ pyfemtet/opt/meta_script/YAML_Generator.xlsm,sha256=2hZKioZfGkH_0ufre8xi2gps8SJUNwgSB_6b9vCc2tI,66648
61
+ pyfemtet/opt/meta_script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
+ pyfemtet/opt/meta_script/__main__.py,sha256=J7RD6aFr67t62tcwgLcoC4GzQ2DdYFxx7z63imro9A4,8061
58
63
  pyfemtet/opt/optimizer/__init__.py,sha256=Ia6viowECkG0IFXtFef0tJ4jDKsoDzJLqMJ9xLFH2LQ,543
59
64
  pyfemtet/opt/optimizer/_base.py,sha256=1TY1iVZdpgJcmF6g3-CcY-6u4REs8_gR_0y9cXUQe2s,12932
60
65
  pyfemtet/opt/optimizer/_optuna/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -133,7 +138,7 @@ pyfemtet/opt/visualization/_complex_components/pm_graph_creator.py,sha256=f-ikYA
133
138
  pyfemtet/opt/visualization/_create_wrapped_components.py,sha256=9AltJHr1DM6imZfpNp867rC-uAYqQ-emdgTLChKDrl8,2513
134
139
  pyfemtet/opt/visualization/_process_monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
135
140
  pyfemtet/opt/visualization/_process_monitor/application.py,sha256=8ShNMPWrD_1IHyPz2a63tlzENQg7by3kg4pdXSuv0_4,8659
136
- pyfemtet/opt/visualization/_process_monitor/pages.py,sha256=-G-zNvYS6HDXrwX0lQlInlJn3rZPr1-Rh4AAAOudmuY,15147
141
+ pyfemtet/opt/visualization/_process_monitor/pages.py,sha256=a94MWLSnjr6bbPqIcAWbvJ3D4bMEP98DvoomSFFkBqE,15711
137
142
  pyfemtet/opt/visualization/_wrapped_components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
138
143
  pyfemtet/opt/visualization/_wrapped_components/dbc.py,sha256=iSh4QRmLIQMfiAWowG1ThXLPhmKluRYOYPcdDFVI0t0,42162
139
144
  pyfemtet/opt/visualization/_wrapped_components/dcc.py,sha256=-Iw6MjFQmvJ__KcddPhFDqui6lk2ixB2U2tZH_Il5pA,17500
@@ -143,8 +148,8 @@ pyfemtet/opt/visualization/result_viewer/.gitignore,sha256=ryvb4aqbbsHireHWlPQfx
143
148
  pyfemtet/opt/visualization/result_viewer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
149
  pyfemtet/opt/visualization/result_viewer/application.py,sha256=WcHBx_J5eNLKSaprpk9BGifwhO04oN8FiNGYTWorrXA,1691
145
150
  pyfemtet/opt/visualization/result_viewer/pages.py,sha256=MZAjzbuq0toZrR-iJhElM3A12_jHVCTt65gz1kdNPbw,32193
146
- pyfemtet-0.8.9.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
147
- pyfemtet-0.8.9.dist-info/METADATA,sha256=7KhkJFd-xgckrqllScrrmO-uAYns2wfa-G8PDR5KSd8,3509
148
- pyfemtet-0.8.9.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
149
- pyfemtet-0.8.9.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
150
- pyfemtet-0.8.9.dist-info/RECORD,,
151
+ pyfemtet-0.8.11.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
152
+ pyfemtet-0.8.11.dist-info/METADATA,sha256=Yg6P6oApQo_63zTEzB4m2Ls3TQCljx_Tddr_T5bWgYs,3549
153
+ pyfemtet-0.8.11.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
154
+ pyfemtet-0.8.11.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
155
+ pyfemtet-0.8.11.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.0.1
2
+ Generator: poetry-core 2.1.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any