pyfemtet 0.4.9__py3-none-any.whl → 0.4.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.

Files changed (73) hide show
  1. pyfemtet/__init__.py +1 -1
  2. pyfemtet/opt/_femopt.py +9 -3
  3. pyfemtet/opt/femprj_sample/wat_ex14_parametric_parallel.py +66 -0
  4. pyfemtet/opt/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py +64 -0
  5. pyfemtet/opt/interface/_femtet.py +32 -10
  6. pyfemtet/opt/interface/_femtet_parametric.py +5 -25
  7. pyfemtet/opt/opt/_base.py +9 -1
  8. pyfemtet/opt/opt/_optuna.py +4 -0
  9. pyfemtet/opt/visualization/__init__.py +0 -7
  10. pyfemtet/opt/visualization/_create_wrapped_components.py +93 -0
  11. pyfemtet/opt/visualization/base.py +254 -0
  12. pyfemtet/opt/visualization/complex_components/__init__.py +0 -0
  13. pyfemtet/opt/visualization/complex_components/alert_region.py +71 -0
  14. pyfemtet/opt/visualization/complex_components/control_femtet.py +195 -0
  15. pyfemtet/opt/visualization/{_graphs.py → complex_components/main_figure_creator.py} +13 -49
  16. pyfemtet/opt/visualization/complex_components/main_graph.py +263 -0
  17. pyfemtet/opt/visualization/process_monitor/__init__.py +0 -0
  18. pyfemtet/opt/visualization/process_monitor/application.py +201 -0
  19. pyfemtet/opt/visualization/process_monitor/pages.py +276 -0
  20. pyfemtet/opt/visualization/result_viewer/.gitignore +1 -0
  21. pyfemtet/opt/visualization/result_viewer/__init__.py +0 -0
  22. pyfemtet/opt/visualization/result_viewer/application.py +44 -0
  23. pyfemtet/opt/visualization/result_viewer/pages.py +692 -0
  24. pyfemtet/opt/visualization/result_viewer/tutorial/tutorial.csv +18 -0
  25. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.jpg +0 -0
  26. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.log +81 -0
  27. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.pdt +0 -0
  28. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_heatflow.csv +28 -0
  29. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_heatflow_el.csv +22 -0
  30. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial1.jpg +0 -0
  31. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial1.pdt +0 -0
  32. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial10.jpg +0 -0
  33. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial10.pdt +0 -0
  34. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial11.jpg +0 -0
  35. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial11.pdt +0 -0
  36. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial12.jpg +0 -0
  37. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial12.pdt +0 -0
  38. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial13.jpg +0 -0
  39. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial13.pdt +0 -0
  40. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial14.jpg +0 -0
  41. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial14.pdt +0 -0
  42. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial15.jpg +0 -0
  43. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial15.pdt +0 -0
  44. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial2.jpg +0 -0
  45. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial2.pdt +0 -0
  46. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial3.jpg +0 -0
  47. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial3.pdt +0 -0
  48. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial4.jpg +0 -0
  49. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial4.pdt +0 -0
  50. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial5.jpg +0 -0
  51. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial5.pdt +0 -0
  52. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial6.jpg +0 -0
  53. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial6.pdt +0 -0
  54. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial7.jpg +0 -0
  55. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial7.pdt +0 -0
  56. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial8.jpg +0 -0
  57. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial8.pdt +0 -0
  58. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial9.jpg +0 -0
  59. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial9.pdt +0 -0
  60. pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.femprj +0 -0
  61. pyfemtet/opt/visualization/wrapped_components/__init__.py +0 -0
  62. pyfemtet/opt/visualization/wrapped_components/dbc.py +1518 -0
  63. pyfemtet/opt/visualization/wrapped_components/dcc.py +609 -0
  64. pyfemtet/opt/visualization/wrapped_components/html.py +3570 -0
  65. pyfemtet/opt/visualization/wrapped_components/str_enum.py +43 -0
  66. {pyfemtet-0.4.9.dist-info → pyfemtet-0.4.11.dist-info}/METADATA +1 -1
  67. pyfemtet-0.4.11.dist-info/RECORD +136 -0
  68. {pyfemtet-0.4.9.dist-info → pyfemtet-0.4.11.dist-info}/entry_points.txt +1 -1
  69. pyfemtet/opt/visualization/_monitor.py +0 -1227
  70. pyfemtet/opt/visualization/result_viewer.py +0 -13
  71. pyfemtet-0.4.9.dist-info/RECORD +0 -81
  72. {pyfemtet-0.4.9.dist-info → pyfemtet-0.4.11.dist-info}/LICENSE +0 -0
  73. {pyfemtet-0.4.9.dist-info → pyfemtet-0.4.11.dist-info}/WHEEL +0 -0
@@ -0,0 +1,276 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ from dash import Output, Input, State, callback_context, no_update, ALL
5
+ from dash.exceptions import PreventUpdate
6
+
7
+ from pyfemtet.opt.visualization.wrapped_components import dcc, dbc, html
8
+ from pyfemtet.opt.visualization.base import AbstractPage, logger
9
+ from pyfemtet.opt.visualization.complex_components.main_graph import MainGraph # , FLEXBOX_STYLE_ALLOW_VERTICAL_FILL
10
+
11
+
12
+ DBC_COLUMN_STYLE_CENTER = {
13
+ 'display': 'flex',
14
+ 'justify-content': 'center',
15
+ 'align-items': 'center',
16
+ }
17
+
18
+ DBC_COLUMN_STYLE_RIGHT = {
19
+ 'display': 'flex',
20
+ 'justify-content': 'right',
21
+ 'align-items': 'right',
22
+ }
23
+
24
+
25
+ def is_iterable(component):
26
+ return hasattr(component, '__len__')
27
+
28
+
29
+ class HomePage(AbstractPage):
30
+
31
+ def __init__(self, title, rel_url='/'):
32
+ super().__init__(title, rel_url)
33
+
34
+ def setup_component(self):
35
+ # main graph
36
+ # noinspection PyAttributeOutsideInit
37
+ self.main_graph: MainGraph = MainGraph()
38
+ self.add_subpage(self.main_graph)
39
+
40
+ # entire optimization status
41
+ # noinspection PyAttributeOutsideInit
42
+ self.entire_status_message = html.H4(
43
+ 'Optimization status will be shown here.',
44
+ className='alert-heading',
45
+ id='optimization-entire-status-message',
46
+ )
47
+ # noinspection PyAttributeOutsideInit
48
+ self.entire_status = dbc.Alert(
49
+ children=self.entire_status_message,
50
+ id='optimization-entire-status',
51
+ color='secondary',
52
+ )
53
+
54
+ # stop update button
55
+ # noinspection PyAttributeOutsideInit
56
+ self.toggle_update_graph_button = dbc.Checkbox(
57
+ label='Auto-update graph',
58
+ class_name='form-switch',
59
+ id='toggle-update-graph',
60
+ value=True,
61
+ )
62
+
63
+ # interrupt button
64
+ # noinspection PyAttributeOutsideInit
65
+ self.interrupt_button = dbc.Button(
66
+ children='Interrupt Optimization',
67
+ color='danger',
68
+ id='interrupt-optimization-button',
69
+ disabled=True,
70
+ )
71
+
72
+ # sync interval
73
+ # noinspection PyAttributeOutsideInit
74
+ self.interval = dcc.Interval(id='process-monitor-home-interval', interval=1000)
75
+
76
+ def setup_layout(self):
77
+ """"""
78
+ """
79
+ =======================
80
+ | | ---------------- |
81
+ | | | | |
82
+ | | | Main Graph | |
83
+ | | | | |
84
+ | | ---------------- |
85
+ | | [stop][interrupt]<---- Buttons
86
+ | | ---------------- |
87
+ | | | Status | |
88
+ | ^| ---------------- |
89
+ ==|====================
90
+ |
91
+ SideBar
92
+ """
93
+ self.layout = dbc.Container(
94
+ children=[
95
+ self.interval,
96
+ self.main_graph.layout,
97
+ self.entire_status,
98
+ dbc.Row(
99
+ children=[
100
+ dbc.Col(self.toggle_update_graph_button),
101
+ dbc.Col(self.interrupt_button, style=DBC_COLUMN_STYLE_RIGHT),
102
+ ],
103
+ ),
104
+ ]
105
+ )
106
+
107
+ def setup_callback(self):
108
+ # setup callback of subpages
109
+ super().setup_callback()
110
+
111
+ from pyfemtet.opt.visualization.process_monitor.application import ProcessMonitorApplication
112
+ from pyfemtet.opt._femopt_core import OptimizationStatus
113
+ self.application: ProcessMonitorApplication = self.application
114
+
115
+ app = self.application.app
116
+
117
+ # ===== Delete Loading Animation =====
118
+ @app.callback(
119
+ Output(self.main_graph.loading.id, self.main_graph.loading.Prop.target_components),
120
+ Input(self.main_graph.graph.id, 'figure'),
121
+ prevent_initial_call=True,
122
+ )
123
+ def disable_loading_animation(_):
124
+ return {}
125
+
126
+ # ===== history data to graph ======
127
+ @app.callback(
128
+ Output(self.main_graph.dummy.id, 'children', allow_duplicate=True), # fire update graph callback
129
+ Input(self.interval.id, self.interval.Prop.n_intervals),
130
+ State(self.toggle_update_graph_button.id, self.toggle_update_graph_button.Prop.value),
131
+ State(self.main_graph.data_length.id, self.main_graph.data_length_prop), # check should update or not
132
+ prevent_initial_call=True,)
133
+ def update_graph(_, update_switch, current_graph_data_length):
134
+ logger.debug('====================')
135
+ logger.debug(f'update_graph called by {callback_context.triggered_id}')
136
+
137
+ current_graph_data_length = 0 if current_graph_data_length is None else current_graph_data_length
138
+
139
+ if callback_context.triggered_id is None:
140
+ raise PreventUpdate
141
+
142
+ # update_switch is unchecked, do nothing
143
+ if not update_switch:
144
+ raise PreventUpdate
145
+
146
+ # If new data does not exist, do nothing
147
+ if len(self.application.local_data) <= current_graph_data_length:
148
+ raise PreventUpdate
149
+
150
+ # fire callback
151
+ return ''
152
+
153
+ # ===== show optimization state =====
154
+ @app.callback(
155
+ Output(self.entire_status.id, self.entire_status.Prop.color),
156
+ Output(self.entire_status_message.id, 'children'),
157
+ Input(self.interval.id, self.interval.Prop.n_intervals),
158
+ prevent_initial_call=False,)
159
+ def update_entire_status(*_):
160
+ # get status message
161
+ status_int = self.application.local_entire_status_int
162
+ msg = OptimizationStatus.const_to_str(status_int)
163
+ color = self.application.get_status_color(status_int)
164
+ return color, msg
165
+
166
+ # ===== Interrupt Optimization and Control Button Disabled =====
167
+ @app.callback(
168
+ Output(self.interrupt_button.id, self.interrupt_button.Prop.disabled),
169
+ Input(self.interrupt_button.id, self.interrupt_button.Prop.n_clicks),
170
+ prevent_initial_call=False,)
171
+ def interrupt_optimization(*_):
172
+ # If page (re)loaded,
173
+ if callback_context.triggered_id is None:
174
+ # Enable only if the entire_state < INTERRUPTING
175
+ if self.application.local_entire_status_int < OptimizationStatus.INTERRUPTING:
176
+ return False
177
+ # Keep disable(default) if process is interrupting or terminating.
178
+ else:
179
+ raise PreventUpdate
180
+
181
+ # If the entire_state < INTERRUPTING, set INTERRUPTING
182
+ if self.application.local_entire_status_int < OptimizationStatus.INTERRUPTING:
183
+ self.application.local_entire_status_int = OptimizationStatus.INTERRUPTING
184
+ return True
185
+
186
+ # keep disabled
187
+ raise PreventUpdate
188
+
189
+ # ===== TEST CODE =====
190
+ if self.application.is_debug:
191
+
192
+ # increment status
193
+ self.layout.children.append(dbc.Button(children='local_status を進める', id='debug-button-1'))
194
+
195
+ @app.callback(Output(self.interval.id, self.interval.Prop.interval),
196
+ Input('debug-button-1', 'n_clicks'),
197
+ prevent_initial_call=True)
198
+ def status_change(*_):
199
+ self.application.local_entire_status_int += 10
200
+ for i in range(len(self.application.local_worker_status_int_list)):
201
+ self.application.local_worker_status_int_list[i] += 10
202
+ raise PreventUpdate
203
+
204
+ # increment data
205
+ self.layout.children.append(dbc.Button(children='local_data を増やす', id='debug-button-2'))
206
+
207
+ @app.callback(Output(self.interval.id, self.interval.Prop.interval, allow_duplicate=True),
208
+ Input('debug-button-2', 'n_clicks'),
209
+ prevent_initial_call=True)
210
+ def add_data(*_):
211
+ metadata = self.application.history.metadata
212
+ df = self.application.local_data
213
+
214
+ new_row = df.iloc[-2:]
215
+ obj_index = np.where(np.array(metadata) == 'obj')[0]
216
+ for idx in obj_index:
217
+ new_row.iloc[:, idx] = np.random.rand(len(new_row))
218
+
219
+ df = pd.concat([df, new_row])
220
+ df.trial = np.array(range(len(df)))
221
+ logger.debug(df)
222
+
223
+ self.application.local_data = df
224
+
225
+ raise PreventUpdate
226
+
227
+
228
+ class WorkerPage(AbstractPage):
229
+
230
+ def __init__(self, title, rel_url, application):
231
+ from pyfemtet.opt.visualization.process_monitor.application import ProcessMonitorApplication
232
+ self.application: ProcessMonitorApplication = None
233
+ super().__init__(title, rel_url, application)
234
+
235
+ def setup_component(self):
236
+ # noinspection PyAttributeOutsideInit
237
+ self.interval = dcc.Interval(id='worker-page-interval', interval=1000)
238
+
239
+ # noinspection PyAttributeOutsideInit
240
+ self.worker_status_alerts = []
241
+ for i in range(len(self.application.worker_addresses)):
242
+ id_worker_alert = f'worker-status-alert-{i}'
243
+ alert = dbc.Alert('worker status here', id=id_worker_alert, color='dark')
244
+ self.worker_status_alerts.append(alert)
245
+
246
+ def setup_layout(self):
247
+ rows = [self.interval]
248
+ rows.extend([dbc.Row([dbc.Col(html.Div(dcc.Loading(alert, id={"type": "loading", "index": i})))]) for i, alert in enumerate(self.worker_status_alerts)])
249
+
250
+ self.layout = dbc.Container(
251
+ children=rows,
252
+ fluid=True,
253
+ )
254
+
255
+ def setup_callback(self):
256
+ app = self.application.app
257
+
258
+ @app.callback(
259
+ [Output(alert.id, 'children') for alert in self.worker_status_alerts],
260
+ [Output(alert.id, 'color') for alert in self.worker_status_alerts],
261
+ Output({"type": "loading", "index": ALL}, "target_components"),
262
+ Input(self.interval.id, 'n_intervals'),
263
+ )
264
+ def update_worker_state(_):
265
+ from pyfemtet.opt._femopt_core import OptimizationStatus
266
+
267
+ ret = []
268
+
269
+ for worker_address, worker_status_int in zip(self.application.worker_addresses, self.application.local_worker_status_int_list):
270
+ worker_status_message = OptimizationStatus.const_to_str(worker_status_int)
271
+ ret.append(f'{worker_address} is {worker_status_message}')
272
+
273
+ ret.extend([self.application.get_status_color(status_int) for status_int in self.application.local_worker_status_int_list])
274
+ ret.append([({} if callback_context.triggered_id is None else no_update) for _ in range(len(self.worker_status_alerts))])
275
+
276
+ return tuple(ret)
@@ -0,0 +1 @@
1
+ sample
File without changes
@@ -0,0 +1,44 @@
1
+ from pyfemtet.opt.visualization.base import PyFemtetApplicationBase
2
+ from pyfemtet.opt.visualization.result_viewer.pages import HomePage
3
+
4
+
5
+ class ResultViewerApplication(PyFemtetApplicationBase):
6
+
7
+ def __init__(self):
8
+ super().__init__(
9
+ title='PyFemtet ResultView',
10
+ subtitle='visualize optimization result',
11
+ history=None,
12
+ )
13
+
14
+ def setup_callback(self):
15
+ super().setup_callback()
16
+
17
+
18
+ def debug():
19
+ import os
20
+ os.chdir(os.path.dirname(__file__))
21
+
22
+ g_application = ResultViewerApplication()
23
+
24
+ g_home_page = HomePage('result')
25
+
26
+ g_application.add_page(g_home_page, 0)
27
+ g_application.setup_callback()
28
+
29
+ g_application.run(debug=True)
30
+
31
+
32
+ def main():
33
+ g_application = ResultViewerApplication()
34
+
35
+ g_home_page = HomePage('result')
36
+
37
+ g_application.add_page(g_home_page, 0)
38
+ g_application.setup_callback()
39
+
40
+ g_application.run()
41
+
42
+
43
+ if __name__ == '__main__':
44
+ debug()