pyfemtet 0.5.3__py3-none-any.whl → 0.6.0__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 (62) hide show
  1. pyfemtet/__init__.py +1 -1
  2. pyfemtet/{message → _message}/locales/ja/LC_MESSAGES/messages.po +89 -77
  3. pyfemtet/{message → _message}/locales/messages.pot +88 -76
  4. pyfemtet/{message → _message}/messages.py +1 -1
  5. pyfemtet/_warning.py +23 -0
  6. pyfemtet/dispatch_extensions/__init__.py +12 -0
  7. pyfemtet/{dispatch_extensions.py → dispatch_extensions/_impl.py} +45 -43
  8. pyfemtet/logger/__init__.py +3 -0
  9. pyfemtet/{logger.py → logger/_impl.py} +12 -6
  10. pyfemtet/opt/__init__.py +3 -0
  11. pyfemtet/opt/_femopt.py +265 -68
  12. pyfemtet/opt/_femopt_core.py +111 -68
  13. pyfemtet/opt/_test_utils/record_history.py +1 -1
  14. pyfemtet/opt/interface/__init__.py +0 -1
  15. pyfemtet/opt/interface/_base.py +3 -3
  16. pyfemtet/opt/interface/_femtet.py +116 -59
  17. pyfemtet/opt/interface/_femtet_with_nx/_interface.py +35 -12
  18. pyfemtet/opt/interface/_femtet_with_sldworks.py +22 -2
  19. pyfemtet/opt/optimizer/__init__.py +5 -1
  20. pyfemtet/opt/optimizer/_base.py +81 -55
  21. pyfemtet/opt/optimizer/{_optuna_botorchsampler_parameter_constraint_helper.py → _optuna/_botorch_patch/enable_nonlinear_constraint.py} +10 -127
  22. pyfemtet/opt/optimizer/{_optuna.py → _optuna/_optuna.py} +122 -19
  23. pyfemtet/opt/optimizer/_optuna/_pof_botorch.py +1833 -0
  24. pyfemtet/opt/optimizer/_scipy.py +20 -5
  25. pyfemtet/opt/optimizer/_scipy_scalar.py +20 -5
  26. pyfemtet/opt/prediction/{base.py → _base.py} +3 -2
  27. pyfemtet/opt/prediction/single_task_gp.py +10 -5
  28. pyfemtet/opt/samples/femprj_sample/constrained_pipe.py +2 -2
  29. pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.py +2 -2
  30. pyfemtet/opt/visualization/{base.py → _base.py} +1 -1
  31. pyfemtet/opt/visualization/{complex_components → _complex_components}/alert_region.py +2 -2
  32. pyfemtet/opt/visualization/{complex_components → _complex_components}/control_femtet.py +3 -3
  33. pyfemtet/opt/visualization/{complex_components → _complex_components}/main_figure_creator.py +1 -1
  34. pyfemtet/opt/visualization/{complex_components → _complex_components}/main_graph.py +5 -5
  35. pyfemtet/opt/visualization/{complex_components → _complex_components}/pm_graph.py +5 -5
  36. pyfemtet/opt/visualization/{complex_components → _complex_components}/pm_graph_creator.py +2 -2
  37. pyfemtet/opt/visualization/_create_wrapped_components.py +2 -2
  38. pyfemtet/opt/visualization/_process_monitor/__init__.py +0 -0
  39. pyfemtet/opt/visualization/{process_monitor → _process_monitor}/application.py +3 -3
  40. pyfemtet/opt/visualization/{process_monitor → _process_monitor}/pages.py +10 -10
  41. pyfemtet/opt/visualization/_wrapped_components/__init__.py +0 -0
  42. pyfemtet/opt/visualization/{wrapped_components → _wrapped_components}/dbc.py +1 -1
  43. pyfemtet/opt/visualization/{wrapped_components → _wrapped_components}/dcc.py +1 -1
  44. pyfemtet/opt/visualization/{wrapped_components → _wrapped_components}/html.py +1 -1
  45. pyfemtet/opt/visualization/result_viewer/application.py +4 -4
  46. pyfemtet/opt/visualization/result_viewer/pages.py +9 -9
  47. {pyfemtet-0.5.3.dist-info → pyfemtet-0.6.0.dist-info}/METADATA +2 -2
  48. {pyfemtet-0.5.3.dist-info → pyfemtet-0.6.0.dist-info}/RECORD +60 -56
  49. {pyfemtet-0.5.3.dist-info → pyfemtet-0.6.0.dist-info}/WHEEL +1 -1
  50. pyfemtet/message/locales/ja/LC_MESSAGES/messages.mo +0 -0
  51. pyfemtet/opt/samples/femprj_sample/.gitignore +0 -2
  52. /pyfemtet/{message → _message}/1. make_pot.bat +0 -0
  53. /pyfemtet/{message → _message}/2. make_mo.bat +0 -0
  54. /pyfemtet/{message → _message}/__init__.py +0 -0
  55. /pyfemtet/{message → _message}/babel.cfg +0 -0
  56. /pyfemtet/opt/{visualization/complex_components → optimizer/_optuna}/__init__.py +0 -0
  57. /pyfemtet/opt/{visualization/process_monitor → optimizer/_optuna/_botorch_patch}/__init__.py +0 -0
  58. /pyfemtet/opt/{parameter.py → optimizer/parameter.py} +0 -0
  59. /pyfemtet/opt/visualization/{wrapped_components → _complex_components}/__init__.py +0 -0
  60. /pyfemtet/opt/visualization/{wrapped_components → _wrapped_components}/str_enum.py +0 -0
  61. {pyfemtet-0.5.3.dist-info → pyfemtet-0.6.0.dist-info}/LICENSE +0 -0
  62. {pyfemtet-0.5.3.dist-info → pyfemtet-0.6.0.dist-info}/entry_points.txt +0 -0
@@ -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: 2024-08-31 04:27+0900\n"
11
+ "POT-Creation-Date: 2024-11-05 16:28+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.15.0\n"
18
+ "Generated-By: Babel 2.16.0\n"
19
19
 
20
20
  #: pyfemtet/message/messages.py:30
21
21
  msgid "hello!"
@@ -201,299 +201,311 @@ msgstr ""
201
201
  msgid "You can use parameter constraint only with BoTorchSampler."
202
202
  msgstr ""
203
203
 
204
- #: pyfemtet/message/messages.py:96
204
+ #: pyfemtet/message/messages.py:93
205
+ msgid "Scipy is deterministic, so whether you set a seed or not will not change the results."
206
+ msgstr ""
207
+
208
+ #: pyfemtet/message/messages.py:94
209
+ msgid "Start to candidate new parameter set with constraints. This process may take a long time."
210
+ msgstr ""
211
+
212
+ #: pyfemtet/message/messages.py:95
213
+ msgid "Updating FEM parameter during evaluating constraints take a long time. Please consider not to use FEM variables in constraint functions and set `update_fem` to False."
214
+ msgstr ""
215
+
216
+ #: pyfemtet/message/messages.py:99
205
217
  msgid "Connect to Femtet"
206
218
  msgstr ""
207
219
 
208
- #: pyfemtet/message/messages.py:97
220
+ #: pyfemtet/message/messages.py:100
209
221
  msgid "Analysis model name described in csv does not exist in project."
210
222
  msgstr ""
211
223
 
212
- #: pyfemtet/message/messages.py:98
224
+ #: pyfemtet/message/messages.py:101
213
225
  msgid "History csv is not read yet. Open your project manually."
214
226
  msgstr ""
215
227
 
216
- #: pyfemtet/message/messages.py:99
228
+ #: pyfemtet/message/messages.py:102
217
229
  msgid "Cannot read project data from csv. Open your project manually."
218
230
  msgstr ""
219
231
 
220
- #: pyfemtet/message/messages.py:100
232
+ #: pyfemtet/message/messages.py:103
221
233
  msgid ".femprj file described in csv is not found. Open your project manually."
222
234
  msgstr ""
223
235
 
224
- #: pyfemtet/message/messages.py:101
236
+ #: pyfemtet/message/messages.py:104
225
237
  msgid "Analysis model name is not specified. Open your model in the project manually."
226
238
  msgstr ""
227
239
 
228
- #: pyfemtet/message/messages.py:103
240
+ #: pyfemtet/message/messages.py:106
229
241
  msgid "Constraint"
230
242
  msgstr ""
231
243
 
232
- #: pyfemtet/message/messages.py:104
244
+ #: pyfemtet/message/messages.py:107
233
245
  msgid "feasible"
234
246
  msgstr ""
235
247
 
236
- #: pyfemtet/message/messages.py:105
248
+ #: pyfemtet/message/messages.py:108
237
249
  msgid "infeasible"
238
250
  msgstr ""
239
251
 
240
- #: pyfemtet/message/messages.py:106
252
+ #: pyfemtet/message/messages.py:109
241
253
  msgid "Optimality"
242
254
  msgstr ""
243
255
 
244
- #: pyfemtet/message/messages.py:107
256
+ #: pyfemtet/message/messages.py:110
245
257
  msgid "non dominated"
246
258
  msgstr ""
247
259
 
248
- #: pyfemtet/message/messages.py:108
260
+ #: pyfemtet/message/messages.py:111
249
261
  msgid "dominated"
250
262
  msgstr ""
251
263
 
252
- #: pyfemtet/message/messages.py:109
264
+ #: pyfemtet/message/messages.py:112
253
265
  msgid "Hypervolume Plot"
254
266
  msgstr ""
255
267
 
256
- #: pyfemtet/message/messages.py:110
268
+ #: pyfemtet/message/messages.py:113
257
269
  msgid "Objective Plot"
258
270
  msgstr ""
259
271
 
260
- #: pyfemtet/message/messages.py:111
272
+ #: pyfemtet/message/messages.py:114
261
273
  msgid "Multi Objective Pair Plot"
262
274
  msgstr ""
263
275
 
264
- #: pyfemtet/message/messages.py:112
276
+ #: pyfemtet/message/messages.py:115
265
277
  msgid "trial number"
266
278
  msgstr ""
267
279
 
268
- #: pyfemtet/message/messages.py:114
280
+ #: pyfemtet/message/messages.py:117
269
281
  msgid "Objectives"
270
282
  msgstr ""
271
283
 
272
- #: pyfemtet/message/messages.py:115
284
+ #: pyfemtet/message/messages.py:118
273
285
  msgid "Objectives (all)"
274
286
  msgstr ""
275
287
 
276
- #: pyfemtet/message/messages.py:117
288
+ #: pyfemtet/message/messages.py:120
277
289
  msgid "Prediction Model"
278
290
  msgstr ""
279
291
 
280
- #: pyfemtet/message/messages.py:118
292
+ #: pyfemtet/message/messages.py:121
281
293
  msgid " Recalculate Model"
282
294
  msgstr ""
283
295
 
284
- #: pyfemtet/message/messages.py:119
296
+ #: pyfemtet/message/messages.py:122
285
297
  msgid " Redraw graph"
286
298
  msgstr ""
287
299
 
288
- #: pyfemtet/message/messages.py:120
300
+ #: pyfemtet/message/messages.py:123
289
301
  msgid "Parameter"
290
302
  msgstr ""
291
303
 
292
- #: pyfemtet/message/messages.py:121
304
+ #: pyfemtet/message/messages.py:124
293
305
  msgid "Parameter2"
294
306
  msgstr ""
295
307
 
296
- #: pyfemtet/message/messages.py:122
308
+ #: pyfemtet/message/messages.py:125
297
309
  msgid "Objective"
298
310
  msgstr ""
299
311
 
300
- #: pyfemtet/message/messages.py:123
312
+ #: pyfemtet/message/messages.py:126
301
313
  msgid "No history selected."
302
314
  msgstr ""
303
315
 
304
- #: pyfemtet/message/messages.py:124
316
+ #: pyfemtet/message/messages.py:127
305
317
  msgid "No FEM result (yet)."
306
318
  msgstr ""
307
319
 
308
- #: pyfemtet/message/messages.py:125
320
+ #: pyfemtet/message/messages.py:128
309
321
  msgid "Prediction model is not calculated yet."
310
322
  msgstr ""
311
323
 
312
- #: pyfemtet/message/messages.py:126
324
+ #: pyfemtet/message/messages.py:129
313
325
  msgid "Cannot select same parameter"
314
326
  msgstr ""
315
327
 
316
- #: pyfemtet/message/messages.py:127
328
+ #: pyfemtet/message/messages.py:130
317
329
  msgid "3D graph (two or more parameters required)"
318
330
  msgstr ""
319
331
 
320
- #: pyfemtet/message/messages.py:129
332
+ #: pyfemtet/message/messages.py:132
321
333
  msgid "Prediction Model of Objective"
322
334
  msgstr ""
323
335
 
324
- #: pyfemtet/message/messages.py:130
336
+ #: pyfemtet/message/messages.py:133
325
337
  msgid "prediction model"
326
338
  msgstr ""
327
339
 
328
- #: pyfemtet/message/messages.py:131
340
+ #: pyfemtet/message/messages.py:134
329
341
  msgid "std. dev. of model"
330
342
  msgstr ""
331
343
 
332
- #: pyfemtet/message/messages.py:133
344
+ #: pyfemtet/message/messages.py:136
333
345
  msgid "Progress"
334
346
  msgstr ""
335
347
 
336
- #: pyfemtet/message/messages.py:134
348
+ #: pyfemtet/message/messages.py:137
337
349
  msgid "Prediction"
338
350
  msgstr ""
339
351
 
340
- #: pyfemtet/message/messages.py:135
352
+ #: pyfemtet/message/messages.py:138
341
353
  msgid "Workers"
342
354
  msgstr ""
343
355
 
344
- #: pyfemtet/message/messages.py:136
356
+ #: pyfemtet/message/messages.py:139
345
357
  msgid "Details"
346
358
  msgstr ""
347
359
 
348
- #: pyfemtet/message/messages.py:138
360
+ #: pyfemtet/message/messages.py:141
349
361
  msgid "Optimization status will be shown here."
350
362
  msgstr ""
351
363
 
352
- #: pyfemtet/message/messages.py:139
364
+ #: pyfemtet/message/messages.py:142
353
365
  msgid "Auto-update graph"
354
366
  msgstr ""
355
367
 
356
- #: pyfemtet/message/messages.py:140
368
+ #: pyfemtet/message/messages.py:143
357
369
  msgid "Interrupt Optimization"
358
370
  msgstr ""
359
371
 
360
- #: pyfemtet/message/messages.py:142
372
+ #: pyfemtet/message/messages.py:145
361
373
  msgid "Result"
362
374
  msgstr ""
363
375
 
364
- #: pyfemtet/message/messages.py:144
376
+ #: pyfemtet/message/messages.py:147
365
377
  msgid "Open Result in Femtet"
366
378
  msgstr ""
367
379
 
368
- #: pyfemtet/message/messages.py:145
380
+ #: pyfemtet/message/messages.py:148
369
381
  msgid "Reconstruct Model"
370
382
  msgstr ""
371
383
 
372
- #: pyfemtet/message/messages.py:146
384
+ #: pyfemtet/message/messages.py:149
373
385
  msgid "Drag and drop or select csv file"
374
386
  msgstr ""
375
387
 
376
- #: pyfemtet/message/messages.py:147
388
+ #: pyfemtet/message/messages.py:150
377
389
  msgid "Connection to Femtet is not established. Launch Femtet and Open a project."
378
390
  msgstr ""
379
391
 
380
- #: pyfemtet/message/messages.py:148
392
+ #: pyfemtet/message/messages.py:151
381
393
  msgid "No result plot is selected."
382
394
  msgstr ""
383
395
 
384
- #: pyfemtet/message/messages.py:149
396
+ #: pyfemtet/message/messages.py:152
385
397
  msgid "The femprj file path in the history csv is not found or valid."
386
398
  msgstr ""
387
399
 
388
- #: pyfemtet/message/messages.py:150
400
+ #: pyfemtet/message/messages.py:153
389
401
  msgid "The model name in the history csv is not found."
390
402
  msgstr ""
391
403
 
392
- #: pyfemtet/message/messages.py:151
404
+ #: pyfemtet/message/messages.py:154
393
405
  msgid ".pdt file is not found. Please check the .Results folder. Note that .pdt file save mode depends on the `save_pdt` argument of FemtetInterface in optimization script(default to `all`)."
394
406
  msgstr ""
395
407
 
396
- #: pyfemtet/message/messages.py:156
408
+ #: pyfemtet/message/messages.py:159
397
409
  msgid "Failed to open "
398
410
  msgstr ""
399
411
 
400
- #: pyfemtet/message/messages.py:157
412
+ #: pyfemtet/message/messages.py:160
401
413
  msgid "Specified model is not in current project. Please check opened project. For example, not \"analysis model only\" but your .femprj file."
402
414
  msgstr ""
403
415
 
404
- #: pyfemtet/message/messages.py:160
416
+ #: pyfemtet/message/messages.py:163
405
417
  msgid ".femprj file path of the history csv is invalid. Please certify matching between csv and opening .femprj file."
406
418
  msgstr ""
407
419
 
408
- #: pyfemtet/message/messages.py:161
420
+ #: pyfemtet/message/messages.py:164
409
421
  msgid "Analysis model name of the history csv is invalid. Please certify matching between csv and opening analysis model."
410
422
  msgstr ""
411
423
 
412
- #: pyfemtet/message/messages.py:162
424
+ #: pyfemtet/message/messages.py:165
413
425
  msgid "Analysis model name of the history csv and opened in Femtet is inconsistent. Please certify matching between csv and opening analysis model."
414
426
  msgstr ""
415
427
 
416
- #: pyfemtet/message/messages.py:163
428
+ #: pyfemtet/message/messages.py:166
417
429
  msgid "tutorial mode"
418
430
  msgstr ""
419
431
 
420
- #: pyfemtet/message/messages.py:164
432
+ #: pyfemtet/message/messages.py:167
421
433
  msgid "Load Sample CSV"
422
434
  msgstr ""
423
435
 
424
- #: pyfemtet/message/messages.py:165
436
+ #: pyfemtet/message/messages.py:168
425
437
  msgid "Load CSV"
426
438
  msgstr ""
427
439
 
428
- #: pyfemtet/message/messages.py:166
440
+ #: pyfemtet/message/messages.py:169
429
441
  msgid "Open your optimization result. Then connecting to femtet will start automatically. Note that in tutorial mode, this button loads the ready-made sample csv and open sample femprj."
430
442
  msgstr ""
431
443
 
432
- #: pyfemtet/message/messages.py:168
444
+ #: pyfemtet/message/messages.py:171
433
445
  msgid "Main Graph"
434
446
  msgstr ""
435
447
 
436
- #: pyfemtet/message/messages.py:169
448
+ #: pyfemtet/message/messages.py:172
437
449
  msgid "Here the optimization history is shown. Each plot represents single FEM result. You can pick a result to open the corresponding result in Femtet. "
438
450
  msgstr ""
439
451
 
440
- #: pyfemtet/message/messages.py:172
452
+ #: pyfemtet/message/messages.py:175
441
453
  msgid "Open Result"
442
454
  msgstr ""
443
455
 
444
- #: pyfemtet/message/messages.py:173
456
+ #: pyfemtet/message/messages.py:176
445
457
  msgid "After pick a point in the main graph, This button shows the corresponding FEM result in Femtet."
446
458
  msgstr ""
447
459
 
448
- #: pyfemtet/message/messages.py:175
460
+ #: pyfemtet/message/messages.py:178
449
461
  msgid "Re-connect to Femtet."
450
462
  msgstr ""
451
463
 
452
- #: pyfemtet/message/messages.py:176
464
+ #: pyfemtet/message/messages.py:179
453
465
  msgid "Sample csv is not found. Please consider to re-install pyfemtet by `py -m pip install pyfemtet -U --force-reinstall`"
454
466
  msgstr ""
455
467
 
456
- #: pyfemtet/message/messages.py:177
468
+ #: pyfemtet/message/messages.py:180
457
469
  msgid "Sample femprj file is not found. Please consider to re-install pyfemtet by `py -m pip install pyfemtet -U --force-reinstall`"
458
470
  msgstr ""
459
471
 
460
- #: pyfemtet/message/messages.py:178
472
+ #: pyfemtet/message/messages.py:181
461
473
  msgid "Sample femprj result folder is not found. Please consider to re-install pyfemtet by `py -m pip install pyfemtet -U --force-reinstall`"
462
474
  msgstr ""
463
475
 
464
- #: pyfemtet/message/messages.py:180
476
+ #: pyfemtet/message/messages.py:183
465
477
  msgid "Loading data..."
466
478
  msgstr ""
467
479
 
468
- #: pyfemtet/message/messages.py:181
480
+ #: pyfemtet/message/messages.py:184
469
481
  msgid "Plots of objectives versus trials"
470
482
  msgstr ""
471
483
 
472
- #: pyfemtet/message/messages.py:182
484
+ #: pyfemtet/message/messages.py:185
473
485
  msgid "The vertical axis is the objective, and the horizontal axis is the number of trials."
474
486
  msgstr ""
475
487
 
476
- #: pyfemtet/message/messages.py:183
488
+ #: pyfemtet/message/messages.py:186
477
489
  msgid "Parallel coordinate plots"
478
490
  msgstr ""
479
491
 
480
- #: pyfemtet/message/messages.py:184
492
+ #: pyfemtet/message/messages.py:187
481
493
  msgid "The vertical axis is an objective or parameters, and one polyline indicates one result."
482
494
  msgstr ""
483
495
 
484
- #: pyfemtet/message/messages.py:185
496
+ #: pyfemtet/message/messages.py:188
485
497
  msgid "The heatmap of objectives"
486
498
  msgstr ""
487
499
 
488
- #: pyfemtet/message/messages.py:186
500
+ #: pyfemtet/message/messages.py:189
489
501
  msgid "The axes are parameters, and the color shows objective value."
490
502
  msgstr ""
491
503
 
492
- #: pyfemtet/message/messages.py:187
504
+ #: pyfemtet/message/messages.py:190
493
505
  msgid "The response of an objective versus one parameter"
494
506
  msgstr ""
495
507
 
496
- #: pyfemtet/message/messages.py:188
508
+ #: pyfemtet/message/messages.py:191
497
509
  msgid "The vertical axis is objective, and the horizontal axis is parameter."
498
510
  msgstr ""
499
511
 
@@ -132,7 +132,7 @@ class Message:
132
132
  GRAPH_TITLE_PREDICTION_MODEL = _('Prediction Model of Objective')
133
133
  LEGEND_LABEL_PREDICTION_MODEL = _('prediction model')
134
134
  LEGEND_LABEL_PREDICTION_MODEL_STDDEV = _('std. dev. of model')
135
- # process_monitor application
135
+ # _process_monitor application
136
136
  PAGE_TITLE_PROGRESS = _('Progress')
137
137
  PAGE_TITLE_PREDICTION_MODEL = _('Prediction')
138
138
  PAGE_TITLE_WORKERS = _('Workers')
pyfemtet/_warning.py ADDED
@@ -0,0 +1,23 @@
1
+ import warnings
2
+ from functools import wraps
3
+
4
+
5
+ def experimental_feature(func):
6
+ @wraps(func)
7
+ def wrapper(*args, **kwargs):
8
+ warnings.warn(f"The function '{func.__name__}' is experimental and may change in the future.",
9
+ category=UserWarning,
10
+ stacklevel=2)
11
+ return func(*args, **kwargs)
12
+ return wrapper
13
+
14
+
15
+ if __name__ == '__main__':
16
+
17
+ # 使用例
18
+ @experimental_feature
19
+ def my_experimental_function():
20
+ print("This is an experimental function.")
21
+
22
+ # 実行すると、警告が表示されます。
23
+ my_experimental_function()
@@ -0,0 +1,12 @@
1
+ from pyfemtet.dispatch_extensions._impl import (
2
+ dispatch_femtet,
3
+ dispatch_specific_femtet,
4
+ launch_and_dispatch_femtet,
5
+ DispatchExtensionException,
6
+ FemtetNotFoundException,
7
+ FemtetConnectionTimeoutError,
8
+ IFemtet,
9
+ _get_pid,
10
+ _get_pids,
11
+ )
12
+
@@ -19,9 +19,9 @@ from multiprocessing.process import _children, _cleanup
19
19
  from multiprocessing.managers import SyncManager
20
20
 
21
21
  import logging
22
- from .logger import get_logger
22
+ from pyfemtet.logger import get_logger
23
23
 
24
- from pyfemtet.message import Msg
24
+ from pyfemtet._message import Msg
25
25
 
26
26
 
27
27
  logger = get_logger('dispatch')
@@ -151,16 +151,19 @@ def _get_subprocess_log_prefix():
151
151
  def launch_and_dispatch_femtet(timeout=DISPATCH_TIMEOUT, strictly_pid_specify=True) -> Tuple[IFemtet, int]:
152
152
  """Launch Femtet by new process and connect to it.
153
153
 
154
+ The wrapper for Dispatch() but returns PID with IFemtet.
155
+
154
156
  Args:
155
- timeout (int or float, optional): Seconds to wait for connection. Defaults to DISPATCH_TIMEOUT.
156
- strictly_pid_specify (bool): If True, try to connect the launched femtet process strictly. If False, launch new process but try to connect any connectable femtet.
157
+ timeout (int, optional): Raises an error if the connection is not established within the specified timeout.
158
+ strictly_pid_specify (bool, optional): Attempts to establish a connection to the launched Femtet strictly.
159
+ This may result in slower processing due to process exclusivity handling.
157
160
 
158
161
  Raises:
159
- FemtetNotFoundException: Launched Femtet is not found for some reason (i.e. failed to launch Femtet).
160
- FemtetConnectionTimeoutError: Connection trial takes over `timeout` seconds by some reason.
162
+ FemtetConnectionTimeoutError: Couldn't connect Femtet process for some reason (i.e. Femtet.exe is not launched).
161
163
 
162
164
  Returns:
163
- Tuple[IFemtet, int]:
165
+ tuple[IFemtet, int]: An object for controlling Femtet and the PID of the Femtet being controlled.
166
+
164
167
  """
165
168
  # launch femtet
166
169
  util.execute_femtet()
@@ -188,6 +191,22 @@ def launch_and_dispatch_femtet(timeout=DISPATCH_TIMEOUT, strictly_pid_specify=Tr
188
191
  def dispatch_femtet(timeout=DISPATCH_TIMEOUT, subprocess_log_prefix='') -> Tuple[IFemtet, int]:
189
192
  """Connect to existing Femtet process.
190
193
 
194
+ The wrapper for Dispatch() but returns PID with IFemtet.
195
+
196
+ Args:
197
+ timeout (int, optional): Raises an error if the connection is not established within the specified timeout.
198
+ subprocess_log_prefix (str, optional): A prefix to output in logs. Typically used only for internal processing.
199
+
200
+ Raises:
201
+ FemtetConnectionTimeoutError: Couldn't connect Femtet process for some reason (i.e. Femtet.exe is not launched).
202
+
203
+ Returns:
204
+ tuple[IFemtet, int]: An object for controlling Femtet and the PID of the Femtet being controlled.
205
+
206
+ """
207
+
208
+ """
209
+
191
210
  Args:
192
211
  timeout (int or float, optional): Seconds to wait for connection. Defaults to DISPATCH_TIMEOUT.
193
212
  subprocess_log_prefix (str, optional): The prefix of log message.
@@ -234,7 +253,6 @@ def dispatch_femtet(timeout=DISPATCH_TIMEOUT, subprocess_log_prefix='') -> Tuple
234
253
  return Femtet, pid
235
254
 
236
255
 
237
-
238
256
  def _block_other_femtets(
239
257
  target_pid,
240
258
  subprocess_idx,
@@ -314,36 +332,7 @@ def _block_other_femtets(
314
332
 
315
333
 
316
334
  def dispatch_specific_femtet(pid, timeout=DISPATCH_TIMEOUT) -> Tuple[IFemtet, int]:
317
- """Connect Femtet whose process id is specified.
318
-
319
- This is a wrapper function of `dispatch_specific_femtet_core`.
320
- When this function is called by dask worker,
321
- the connection is processed exclusively.
322
-
323
- Args:
324
- pid (int): Process id of Femtet that you want to connect.
325
- timeout (int or float, optional): Seconds to wait for connection. Defaults to DISPATCH_TIMEOUT.
326
-
327
- Raises:
328
- FemtetNotFoundException: Femtet whose process id is `pid` doesn't exist.
329
- FemtetConnectionTimeoutError: Connection trial takes over `timeout` seconds by some reason.
330
-
331
- Returns:
332
- Tuple[IFemtet, int]:
333
- """
334
- try:
335
- with Lock('dispatch-specific-femtet'):
336
- return dispatch_specific_femtet_core(pid, timeout)
337
- except RuntimeError as e:
338
- if 'object not properly initialized' in str(e):
339
- pass
340
- else:
341
- raise e
342
- return dispatch_specific_femtet_core(pid, timeout) # for logger, out of except.
343
-
344
-
345
- def dispatch_specific_femtet_core(pid, timeout=DISPATCH_TIMEOUT) -> Tuple[IFemtet, int]:
346
- """Connect Femtet whose process id is specified.
335
+ """Connect Existing Femtet whose process id is specified.
347
336
 
348
337
  Warnings:
349
338
  Once Femtet is connected a python process,
@@ -368,16 +357,29 @@ def dispatch_specific_femtet_core(pid, timeout=DISPATCH_TIMEOUT) -> Tuple[IFemte
368
357
  please consider parallel processing.
369
358
 
370
359
  Args:
371
- pid (int): Process id of Femtet that you want to connect.
372
- timeout (int or float, optional): Seconds to wait for connection. Defaults to 10.
360
+ timeout (int, optional): Raises an error if the connection is not established within the specified timeout.
373
361
 
374
362
  Raises:
375
- FemtetNotFoundException: Femtet whose process id is `pid` doesn't exist.
376
- FemtetConnectionTimeoutError: Connection trial takes over `timeout` seconds by some reason.
363
+ FemtetConnectionTimeoutError: Couldn't connect Femtet process for some reason (i.e. Femtet.exe is not launched).
377
364
 
378
365
  Returns:
379
- Tuple[IFemtet, int]:
366
+ tuple[IFemtet, int]: An object for controlling Femtet and the PID of the Femtet being controlled.
367
+
368
+
380
369
  """
370
+ try:
371
+ with Lock('dispatch-specific-femtet'):
372
+ return _dispatch_specific_femtet_core(pid, timeout)
373
+ except RuntimeError as e:
374
+ if 'object not properly initialized' in str(e):
375
+ pass
376
+ else:
377
+ raise e
378
+ return _dispatch_specific_femtet_core(pid, timeout) # for logger, out of except.
379
+
380
+
381
+ def _dispatch_specific_femtet_core(pid, timeout=DISPATCH_TIMEOUT) -> Tuple[IFemtet, int]:
382
+
381
383
  # TODO: 安定性を見て lock_main を復活させるか決める
382
384
 
383
385
  if timeout < 5:
@@ -0,0 +1,3 @@
1
+ from pyfemtet.logger._impl import get_logger
2
+
3
+ __all__ = ['get_logger']
@@ -5,9 +5,6 @@ from colorlog import ColoredFormatter
5
5
  from dask.distributed import get_worker
6
6
 
7
7
 
8
- __all__ = ['get_logger']
9
-
10
-
11
8
  def _get_worker_name_as_prefix():
12
9
  name = '(Main) '
13
10
  try:
@@ -21,7 +18,7 @@ def _get_worker_name_as_prefix():
21
18
  return name
22
19
 
23
20
 
24
- class DaskLogRecord(logging.LogRecord):
21
+ class _DaskLogRecord(logging.LogRecord):
25
22
  """Generate a log message with dask worker name."""
26
23
 
27
24
  # def __init__(self, *args, **kwargs):
@@ -43,7 +40,7 @@ class DaskLogRecord(logging.LogRecord):
43
40
  return msg
44
41
 
45
42
 
46
- logging.setLogRecordFactory(DaskLogRecord) # すべての logging %(message)s の前に prefix を入れる
43
+ logging.setLogRecordFactory(_DaskLogRecord) # すべての logging %(message)s の前に prefix を入れる
47
44
 
48
45
 
49
46
  def _color_supported() -> bool:
@@ -88,7 +85,16 @@ def _create_formatter() -> logging.Formatter:
88
85
 
89
86
 
90
87
  def get_logger(logger_name):
91
- """Return a logger with a default ColoredFormatter."""
88
+ """Returns a logger.
89
+
90
+ Examples:
91
+ >>> # Retrieves a specific logger used in pyfemtet.opt.
92
+ >>> import logging # doctest: +SKIP
93
+ >>> from pyfemtet.logger import get_logger # doctest: +SKIP
94
+ >>> logger = get_logger('opt') # logger of optimizer # doctest: +SKIP
95
+ >>> logger.setLevel(logging.ERROR) # disable all log from optimizer # doctest: +SKIP
96
+
97
+ """
92
98
 
93
99
  formatter = _create_formatter()
94
100
 
pyfemtet/opt/__init__.py CHANGED
@@ -9,6 +9,8 @@ from pyfemtet.opt.optimizer import AbstractOptimizer
9
9
 
10
10
  from pyfemtet.opt._femopt import FEMOpt
11
11
 
12
+ from pyfemtet.opt._femopt_core import History
13
+
12
14
 
13
15
  __all__ = [
14
16
  'FEMOpt',
@@ -21,4 +23,5 @@ __all__ = [
21
23
  'OptunaOptimizer',
22
24
  'ScipyScalarOptimizer',
23
25
  'ScipyOptimizer',
26
+ 'History',
24
27
  ]