FAST-PEDAGO 1.1.0__tar.gz

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.
Files changed (71) hide show
  1. fast_pedago-1.1.0/PKG-INFO +68 -0
  2. fast_pedago-1.1.0/README.md +30 -0
  3. fast_pedago-1.1.0/fast_pedago/__init__.py +0 -0
  4. fast_pedago-1.1.0/fast_pedago/app.py +122 -0
  5. fast_pedago-1.1.0/fast_pedago/configuration/__init__.py +0 -0
  6. fast_pedago-1.1.0/fast_pedago/configuration/oad_optim_sensitivity_analysis.yml +63 -0
  7. fast_pedago-1.1.0/fast_pedago/configuration/oad_sizing_sensitivity_analysis.yml +61 -0
  8. fast_pedago-1.1.0/fast_pedago/gui/__init__.py +3 -0
  9. fast_pedago-1.1.0/fast_pedago/gui/app_interface.py +345 -0
  10. fast_pedago-1.1.0/fast_pedago/gui/components/__init__.py +33 -0
  11. fast_pedago-1.1.0/fast_pedago/gui/components/app_layout.py +275 -0
  12. fast_pedago-1.1.0/fast_pedago/gui/components/input_widgets.py +508 -0
  13. fast_pedago-1.1.0/fast_pedago/gui/components/inputs_container.py +612 -0
  14. fast_pedago-1.1.0/fast_pedago/gui/components/output_figures_container.py +159 -0
  15. fast_pedago-1.1.0/fast_pedago/gui/components/process_figures_container.py +209 -0
  16. fast_pedago-1.1.0/fast_pedago/gui/components/tutorial_container.py +324 -0
  17. fast_pedago-1.1.0/fast_pedago/gui/resources/__init__.py +3 -0
  18. fast_pedago-1.1.0/fast_pedago/gui/resources/background.jpg +0 -0
  19. fast_pedago-1.1.0/fast_pedago/gui/resources/logo_airbus.png +0 -0
  20. fast_pedago-1.1.0/fast_pedago/gui/resources/logo_fast_oad_main_menu.jpg +0 -0
  21. fast_pedago-1.1.0/fast_pedago/gui/resources/logo_fast_oad_top_layer.jpg +0 -0
  22. fast_pedago-1.1.0/fast_pedago/gui/resources/logo_supaero.png +0 -0
  23. fast_pedago-1.1.0/fast_pedago/gui/resources/tutorial/MDA.png +0 -0
  24. fast_pedago-1.1.0/fast_pedago/gui/resources/tutorial/__init__.py +3 -0
  25. fast_pedago-1.1.0/fast_pedago/gui/resources/tutorial/inputs.gif +0 -0
  26. fast_pedago-1.1.0/fast_pedago/gui/resources/tutorial/launch.gif +0 -0
  27. fast_pedago-1.1.0/fast_pedago/gui/resources/tutorial/n2.gif +0 -0
  28. fast_pedago-1.1.0/fast_pedago/gui/resources/tutorial/outputs.gif +0 -0
  29. fast_pedago-1.1.0/fast_pedago/gui/resources/tutorial/text.py +93 -0
  30. fast_pedago-1.1.0/fast_pedago/notebook/FAST_OAD_app.ipynb +37 -0
  31. fast_pedago-1.1.0/fast_pedago/notebook/__init__.py +0 -0
  32. fast_pedago-1.1.0/fast_pedago/notebook/data/__init__.py +0 -0
  33. fast_pedago-1.1.0/fast_pedago/notebook/data/n2.html +14769 -0
  34. fast_pedago-1.1.0/fast_pedago/notebook/data/n2.png +0 -0
  35. fast_pedago-1.1.0/fast_pedago/notebook/data/oad_optim_sensitivity_analysis.yml +63 -0
  36. fast_pedago-1.1.0/fast_pedago/notebook/data/oad_sizing_sensitivity_analysis.yml +61 -0
  37. fast_pedago-1.1.0/fast_pedago/notebook/data/xdsm.html +407 -0
  38. fast_pedago-1.1.0/fast_pedago/notebook/data/xdsm.png +0 -0
  39. fast_pedago-1.1.0/fast_pedago/notebook/workdir/inputs/reference_aircraft_input_file.xml +553 -0
  40. fast_pedago-1.1.0/fast_pedago/notebook/workdir/outputs/reference_aircraft_cases.sql +0 -0
  41. fast_pedago-1.1.0/fast_pedago/notebook/workdir/outputs/reference_aircraft_flight_points.csv +14 -0
  42. fast_pedago-1.1.0/fast_pedago/notebook/workdir/outputs/reference_aircraft_output_file.xml +1096 -0
  43. fast_pedago-1.1.0/fast_pedago/plots/__init__.py +44 -0
  44. fast_pedago-1.1.0/fast_pedago/plots/functions/__init__.py +27 -0
  45. fast_pedago-1.1.0/fast_pedago/plots/functions/aircraft_front_view.py +354 -0
  46. fast_pedago-1.1.0/fast_pedago/plots/functions/aircraft_side_view.py +401 -0
  47. fast_pedago-1.1.0/fast_pedago/plots/functions/aircraft_top_view.py +511 -0
  48. fast_pedago-1.1.0/fast_pedago/plots/functions/better_mission_viewer.py +52 -0
  49. fast_pedago-1.1.0/fast_pedago/plots/functions/flaps_and_slats.py +304 -0
  50. fast_pedago-1.1.0/fast_pedago/plots/functions/objectives_viewer.py +104 -0
  51. fast_pedago-1.1.0/fast_pedago/plots/functions/polar_with_lift_to_drag_ratio.py +91 -0
  52. fast_pedago-1.1.0/fast_pedago/plots/functions/residuals_viewer.py +98 -0
  53. fast_pedago-1.1.0/fast_pedago/plots/functions/simplified_payload_range.py +149 -0
  54. fast_pedago-1.1.0/fast_pedago/plots/functions/stability_diagram.py +260 -0
  55. fast_pedago-1.1.0/fast_pedago/plots/functions/static_margin.py +175 -0
  56. fast_pedago-1.1.0/fast_pedago/plots/functions/wing.py +716 -0
  57. fast_pedago-1.1.0/fast_pedago/plots/output_graphs_plotter.py +302 -0
  58. fast_pedago-1.1.0/fast_pedago/plots/plot_constants.py +42 -0
  59. fast_pedago-1.1.0/fast_pedago/plots/plot_signatures.py +180 -0
  60. fast_pedago-1.1.0/fast_pedago/processes/__init__.py +3 -0
  61. fast_pedago-1.1.0/fast_pedago/processes/process_launcher.py +415 -0
  62. fast_pedago-1.1.0/fast_pedago/source_data_files/A321_like_source_data_file.xml +554 -0
  63. fast_pedago-1.1.0/fast_pedago/source_data_files/A350_like_source_data_file.xml +553 -0
  64. fast_pedago-1.1.0/fast_pedago/source_data_files/CeRAS01_source_data_file.xml +1023 -0
  65. fast_pedago-1.1.0/fast_pedago/source_data_files/__init__.py +0 -0
  66. fast_pedago-1.1.0/fast_pedago/source_data_files/reference_aircraft_source_data_file.xml +552 -0
  67. fast_pedago-1.1.0/fast_pedago/utils/__init__.py +53 -0
  68. fast_pedago-1.1.0/fast_pedago/utils/functions.py +66 -0
  69. fast_pedago-1.1.0/fast_pedago/utils/path_manager.py +274 -0
  70. fast_pedago-1.1.0/fast_pedago/utils/paths.py +36 -0
  71. fast_pedago-1.1.0/pyproject.toml +101 -0
@@ -0,0 +1,68 @@
1
+ Metadata-Version: 2.4
2
+ Name: FAST-PEDAGO
3
+ Version: 1.1.0
4
+ Summary: Lightweight interface to perform simplified OAD analysis using FAST-OAD
5
+ License-Expression: GPL-3.0-only
6
+ Keywords: aircraft,design,multi-disciplinary,teaching,educational
7
+ Author: Ousmane SY
8
+ Author-email: Ousmane.SY@isae-supaero.fr
9
+ Maintainer: Florent LUTZ
10
+ Maintainer-email: Florent.LUTZ2@isae-supaero.fr
11
+ Requires-Python: >=3.10,<3.15
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Education
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
17
+ Classifier: Natural Language :: English
18
+ Classifier: Operating System :: MacOS
19
+ Classifier: Operating System :: Microsoft :: Windows
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: 3.14
27
+ Classifier: Topic :: Scientific/Engineering :: Physics
28
+ Requires-Dist: appmode (>=0.9.0)
29
+ Requires-Dist: click (>=8.0.3)
30
+ Requires-Dist: fast-oad-core (>=1.10.0)
31
+ Requires-Dist: fast-oad-cs25 (>=0.9.1)
32
+ Requires-Dist: ipyvuetify (>=3.0.0)
33
+ Requires-Dist: ipywidgets (>=7.7.2)
34
+ Requires-Dist: lxml_html_clean
35
+ Requires-Dist: voila (>=0.3.7)
36
+ Project-URL: Homepage, https://github.com/supaero-aircraft-design/FAST-PEDAGO
37
+ Description-Content-Type: text/markdown
38
+
39
+ # FAST-OAD TRAINING AND INCREMENTAL DEVELOPMENT BRANCH
40
+
41
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/supaero-aircraft-design/FAST-PEDAGO/HEAD?labpath=fast_pedago%2Fnotebook%2FFAST_OAD_app.ipynb)
42
+
43
+ This package offers a lightweight interface to perform simplified OAD analysis using FAST-OAD (https://github.com/fast-aircraft-design/FAST-OAD).
44
+
45
+ Want to try quickly ?
46
+ -------
47
+
48
+ You can open the app on a [Binder-hosted Jupyter notebook](https://mybinder.org/v2/gh/supaero-aircraft-design/FAST-PEDAGO/HEAD?labpath=fast_pedago%2Fnotebook%2FFAST_OAD_app.ipynb)
49
+
50
+ Install
51
+ -------
52
+
53
+ **Prerequisite**: FAST-PEDAGO needs at least **Python 3.7.0**.
54
+
55
+ It is recommended (but not required) to install FAST-PEDAGO in a virtual
56
+ environment ([conda](https://docs.conda.io/en/latest/),
57
+ [venv](https://docs.python.org/3.7/library/venv.html), ...).
58
+
59
+ Once Python is installed, FAST-PEDAGO can be installed using pip, by doing the following:
60
+
61
+ ``` {.bash}
62
+ $ pip install fast-pedago
63
+ ```
64
+
65
+ Once installed the cde can be run by doing the following:
66
+ ``` {.bash}
67
+ $ fast-pedago run
68
+ ```
@@ -0,0 +1,30 @@
1
+ # FAST-OAD TRAINING AND INCREMENTAL DEVELOPMENT BRANCH
2
+
3
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/supaero-aircraft-design/FAST-PEDAGO/HEAD?labpath=fast_pedago%2Fnotebook%2FFAST_OAD_app.ipynb)
4
+
5
+ This package offers a lightweight interface to perform simplified OAD analysis using FAST-OAD (https://github.com/fast-aircraft-design/FAST-OAD).
6
+
7
+ Want to try quickly ?
8
+ -------
9
+
10
+ You can open the app on a [Binder-hosted Jupyter notebook](https://mybinder.org/v2/gh/supaero-aircraft-design/FAST-PEDAGO/HEAD?labpath=fast_pedago%2Fnotebook%2FFAST_OAD_app.ipynb)
11
+
12
+ Install
13
+ -------
14
+
15
+ **Prerequisite**: FAST-PEDAGO needs at least **Python 3.7.0**.
16
+
17
+ It is recommended (but not required) to install FAST-PEDAGO in a virtual
18
+ environment ([conda](https://docs.conda.io/en/latest/),
19
+ [venv](https://docs.python.org/3.7/library/venv.html), ...).
20
+
21
+ Once Python is installed, FAST-PEDAGO can be installed using pip, by doing the following:
22
+
23
+ ``` {.bash}
24
+ $ pip install fast-pedago
25
+ ```
26
+
27
+ Once installed the cde can be run by doing the following:
28
+ ``` {.bash}
29
+ $ fast-pedago run
30
+ ```
File without changes
@@ -0,0 +1,122 @@
1
+ import logging
2
+ import os
3
+ import shutil
4
+ import sys
5
+ from argparse import (
6
+ ArgumentDefaultsHelpFormatter,
7
+ ArgumentParser,
8
+ RawDescriptionHelpFormatter,
9
+ )
10
+ from pathlib import Path
11
+
12
+ MAIN_NOTEBOOK_NAME = "FAST_OAD_app.ipynb"
13
+ MAIN_NOTEBOOK_PATH = Path(__file__).parent / "notebook" / MAIN_NOTEBOOK_NAME
14
+
15
+
16
+ class Main:
17
+ """
18
+ Class for managing command line and doing associated actions
19
+ """
20
+
21
+ def __init__(self):
22
+ class _CustomFormatter(RawDescriptionHelpFormatter, ArgumentDefaultsHelpFormatter):
23
+ pass
24
+
25
+ self.parser = ArgumentParser(
26
+ description="FAST pedagogical branch main program",
27
+ formatter_class=_CustomFormatter,
28
+ )
29
+
30
+ @staticmethod
31
+ def _run(args):
32
+ """Run FAST pedagogical branch locally or with server configuration."""
33
+ machine = "server" if args.server else "local"
34
+ print(MAIN_NOTEBOOK_PATH)
35
+ if machine == "server":
36
+ command = (
37
+ "voila "
38
+ "--port=8080 "
39
+ "--no-browser "
40
+ "--MappingKernelManager.cull_idle_timeout=7200 "
41
+ r"""--VoilaConfiguration.file_whitelist="['.*\."""
42
+ """(png|jpg|gif|xlsx|ico|pdf|json)']" """
43
+ )
44
+ else:
45
+ command = (
46
+ "voila "
47
+ r"""--VoilaConfiguration.file_whitelist="['.*\."""
48
+ """s(png|jpg|gif|xlsx|ico|pdf|json)']" """
49
+ )
50
+
51
+ # To not get an ugly error message when you ctrl+c
52
+ try:
53
+ os.system(command + str(MAIN_NOTEBOOK_PATH)) # noqa: S605 this is a literal string, it can be considered safe.
54
+ except KeyboardInterrupt:
55
+ sys.exit()
56
+
57
+ @staticmethod
58
+ def _copy_notebook(args):
59
+ # Should be a pathlib Path already
60
+ requested_destination = args.destination
61
+ if requested_destination.exists() and not requested_destination.is_dir():
62
+ print("Input path should be the path to a directory. Exiting")
63
+ raise SystemExit(1)
64
+
65
+ requested_destination.mkdir(parents=True, exist_ok=True)
66
+
67
+ shutil.copy(MAIN_NOTEBOOK_PATH, args.destination)
68
+ print("You may now run Jupyter with:")
69
+ print(f' jupyter lab "{MAIN_NOTEBOOK_NAME}"')
70
+ return 0
71
+
72
+ # ENTRY POINT ============================================================
73
+ def run(self):
74
+ """Main function."""
75
+ subparsers = self.parser.add_subparsers(title="sub-commands")
76
+
77
+ # sub-command for running FAST-PEDAGO -----------------------------------
78
+ parser_run = subparsers.add_parser(
79
+ "run",
80
+ help="run FAST-OAD pedagogical branch",
81
+ description="run FAST-OAD pedagogical branch",
82
+ )
83
+
84
+ parser_run.add_argument(
85
+ "--server",
86
+ action="store_true",
87
+ help="to be used if ran on server",
88
+ )
89
+ parser_run.set_defaults(func=self._run)
90
+
91
+ # subcommand for copying the notebook ----------------------------------
92
+ parser_copy = subparsers.add_parser(
93
+ "copy_notebook",
94
+ help="copy notebook to target directory to run without voila",
95
+ description="copy notebook to target directory to run without voila",
96
+ )
97
+
98
+ parser_copy.add_argument(
99
+ "-d",
100
+ "--destination",
101
+ type=Path,
102
+ required=True,
103
+ help="Location in which to copy the notebook.",
104
+ )
105
+ parser_copy.set_defaults(func=self._copy_notebook)
106
+
107
+ # Parse --------------------------------------------------------------
108
+ args = self.parser.parse_args()
109
+ try:
110
+ args.func(args)
111
+ except AttributeError:
112
+ self.parser.print_help()
113
+
114
+
115
+ def main():
116
+ log_format = "%(levelname)-8s: %(message)s"
117
+ logging.basicConfig(level=logging.INFO, format=log_format)
118
+ Main().run()
119
+
120
+
121
+ if __name__ == "__main__":
122
+ main()
@@ -0,0 +1,63 @@
1
+ title: Sample OAD Process
2
+
3
+ input_file: ../workdir/inputs/reference_aircraft_input_file.xml
4
+ output_file: ../workdir/outputs/reference_aircraft_output_file.xml
5
+
6
+ driver: om.ScipyOptimizeDriver(tol=1e-2, optimizer='COBYLA')
7
+
8
+ model:
9
+
10
+ # Solvers are defined assuming the OpenMDAO convention "import openmdao.api as om"
11
+ nonlinear_solver: om.NonlinearBlockGS(maxiter=100, rtol=1e-2)
12
+ linear_solver: om.DirectSolver()
13
+
14
+
15
+ # Components can be put in sub-groups
16
+ subgroup:
17
+
18
+ # A group can be set with its own solvers.
19
+ # Uncomment the 2 next lines for using the performance module with "mission_file_path: ::sizing_mission"
20
+ # nonlinear_solver: om.NonlinearBlockGS(maxiter=100, atol=1e-2, iprint=0)
21
+ # linear_solver: om.DirectSolver()
22
+
23
+ geometry:
24
+ # An OpenMDAO component is identified by its "id"
25
+ id: fastoad.geometry.legacy
26
+ weight:
27
+ id: fastoad.weight.legacy
28
+ payload_from_npax: false
29
+ loads:
30
+ id: fastoad.loads.legacy
31
+ mtow:
32
+ id: fastoad.mass_performances.compute_MTOW
33
+ hq_tail_sizing:
34
+ id: fastoad.handling_qualities.tail_sizing
35
+ hq_static_margin:
36
+ id: fastoad.handling_qualities.static_margin
37
+ wing_position:
38
+ id: fastoad.loop.wing_position
39
+ aerodynamics_highspeed:
40
+ id: fastoad.aerodynamics.highspeed.legacy
41
+ aerodynamics_lowspeed:
42
+ id: fastoad.aerodynamics.lowspeed.legacy
43
+ aerodynamics_takeoff:
44
+ id: fastoad.aerodynamics.takeoff.legacy
45
+ aerodynamics_landing:
46
+ id: fastoad.aerodynamics.landing.legacy
47
+ use_xfoil: false
48
+ performance:
49
+ id: fastoad.performances.mission
50
+ propulsion_id: fastoad.wrapper.propulsion.rubber_engine
51
+ mission_file_path: ::sizing_breguet
52
+ out_file: ../workdir/outputs/flight_points.csv
53
+ adjust_fuel: true
54
+ is_sizing: true
55
+ wing_area:
56
+ id: fastoad.loop.wing_area
57
+
58
+ model_options:
59
+ "*":
60
+ use_inner_solvers: false
61
+
62
+ submodels:
63
+ service.aerodynamics.oswald_coefficient: null
@@ -0,0 +1,61 @@
1
+ title: Sample OAD Process
2
+
3
+ input_file: ../workdir/inputs/reference_aircraft_input_file.xml
4
+ output_file: ../workdir/outputs/reference_aircraft_output_file.xml
5
+
6
+ model:
7
+
8
+ # Solvers are defined assuming the OpenMDAO convention "import openmdao.api as om"
9
+ nonlinear_solver: om.NonlinearBlockGS(maxiter=100, rtol=1e-5)
10
+ linear_solver: om.DirectSolver()
11
+
12
+
13
+ # Components can be put in sub-groups
14
+ subgroup:
15
+
16
+ # A group can be set with its own solvers.
17
+ # Uncomment the 2 next lines for using the performance module with "mission_file_path: ::sizing_mission"
18
+ # nonlinear_solver: om.NonlinearBlockGS(maxiter=100, atol=1e-2, iprint=0)
19
+ # linear_solver: om.DirectSolver()
20
+
21
+ geometry:
22
+ # An OpenMDAO component is identified by its "id"
23
+ id: fastoad.geometry.legacy
24
+ weight:
25
+ id: fastoad.weight.legacy
26
+ payload_from_npax: false
27
+ loads:
28
+ id: fastoad.loads.legacy
29
+ mtow:
30
+ id: fastoad.mass_performances.compute_MTOW
31
+ hq_tail_sizing:
32
+ id: fastoad.handling_qualities.tail_sizing
33
+ hq_static_margin:
34
+ id: fastoad.handling_qualities.static_margin
35
+ wing_position:
36
+ id: fastoad.loop.wing_position
37
+ aerodynamics_highspeed:
38
+ id: fastoad.aerodynamics.highspeed.legacy
39
+ aerodynamics_lowspeed:
40
+ id: fastoad.aerodynamics.lowspeed.legacy
41
+ aerodynamics_takeoff:
42
+ id: fastoad.aerodynamics.takeoff.legacy
43
+ aerodynamics_landing:
44
+ id: fastoad.aerodynamics.landing.legacy
45
+ use_xfoil: false
46
+ performance:
47
+ id: fastoad.performances.mission
48
+ propulsion_id: fastoad.wrapper.propulsion.rubber_engine
49
+ mission_file_path: ::sizing_breguet
50
+ out_file: ../workdir/outputs/flight_points.csv
51
+ adjust_fuel: true
52
+ is_sizing: true
53
+ wing_area:
54
+ id: fastoad.loop.wing_area
55
+
56
+ model_options:
57
+ "*":
58
+ use_inner_solvers: false
59
+
60
+ submodels:
61
+ service.aerodynamics.oswald_coefficient: null
@@ -0,0 +1,3 @@
1
+ from .app_interface import AppInterface
2
+
3
+ __all__ = ["AppInterface"]
@@ -0,0 +1,345 @@
1
+ import logging
2
+
3
+ import ipyvuetify as v
4
+
5
+ from fast_pedago.processes import (
6
+ ProcessLauncher,
7
+ )
8
+ from fast_pedago.utils import PathManager
9
+
10
+ from .components import (
11
+ Drawer,
12
+ Footer,
13
+ Header,
14
+ InputsContainer,
15
+ OutputFiguresContainer,
16
+ ProcessFiguresContainer,
17
+ TutorialContainer,
18
+ )
19
+
20
+ _LOGGER = logging.getLogger(__name__)
21
+
22
+ # As there are margins and padding in the voila template,
23
+ # I have to adjust the padding considering both the spacings
24
+ # in the voila template and the other components sizes.
25
+ TOP_PADDING = "76px"
26
+ LEFT_PADDING = "426px"
27
+
28
+
29
+ class AppInterface(v.App):
30
+ def __init__(self, **kwargs):
31
+ super().__init__(**kwargs)
32
+
33
+ PathManager.build_paths()
34
+
35
+ # The process toggle starts on MDA and only reports later changes
36
+ self.is_MDO = False
37
+
38
+ # Sets MDA/MDO launcher to run MDA/MDO.
39
+ self.process_launcher = ProcessLauncher()
40
+
41
+ self._build_layout()
42
+ self._to_tutorial()
43
+
44
+ def _to_tutorial(self):
45
+ """
46
+ Displays tutorial.
47
+ """
48
+ self.footer.start_button.show()
49
+ self.drawer.hide()
50
+ self.header.open_drawer_button.hide()
51
+ self.padding_column.hide()
52
+ self.main_content.children = [self.tutorial]
53
+ self.output_figures.hide_graphs()
54
+
55
+ def _to_main(self):
56
+ """
57
+ Displays main window, with input drawer and tabs to change
58
+ between residuals/objectives graph and output figures.
59
+ """
60
+ self.footer.start_button.hide()
61
+ self.drawer.show()
62
+ self.header.open_drawer_button.show()
63
+ self.padding_column.show()
64
+ self.drawer.content.children = [self.inputs]
65
+ self.main_content.children = [self.graphs]
66
+
67
+ def _switch_tab(self, change):
68
+ """
69
+ Hides the drawer when on outputs tabs, and show it when on
70
+ inputs tab.
71
+
72
+ To be called with "observe" method of a widget.
73
+ """
74
+ data = change["new"]
75
+
76
+ if data == "outputs":
77
+ self.drawer.hide()
78
+ self.header.open_drawer_button.hide()
79
+ self.padding_column.hide()
80
+ else:
81
+ self.drawer.show()
82
+ self.header.open_drawer_button.show()
83
+ self.padding_column.show()
84
+
85
+ self.graphs_window.v_model = data
86
+
87
+ def _build_layout(self):
88
+ """
89
+ Builds the layout of the app: all the app components (drawer,
90
+ input/output tabs, header, footer, tutorial).
91
+ """
92
+ # tutorial widgets
93
+ self.tutorial = TutorialContainer()
94
+
95
+ # Inputs + process graph widgets
96
+ self.process_figures = ProcessFiguresContainer()
97
+
98
+ self.inputs = InputsContainer(self.process_launcher)
99
+
100
+ self.inputs.source_data_file_selector.observe(
101
+ self._set_source_data_file,
102
+ names="v_model",
103
+ )
104
+ self.inputs.process_selection_switch.observe(
105
+ self._switch_process,
106
+ names="v_model",
107
+ )
108
+ self.inputs.launch_button.on_event("click", self._launch_process)
109
+
110
+ self.output_figures = OutputFiguresContainer()
111
+
112
+ self.main_content = v.Container(
113
+ class_="pt-0",
114
+ fluid=True,
115
+ fill_height=True,
116
+ )
117
+
118
+ self.graphs_tabs = v.Tabs(
119
+ v_model="inputs",
120
+ align_tabs="center",
121
+ grow=True,
122
+ hide_slider=True,
123
+ children=[
124
+ v.Tab(
125
+ value="inputs",
126
+ children=["Inputs"],
127
+ ),
128
+ v.Tab(
129
+ value="outputs",
130
+ children=["Outputs"],
131
+ ),
132
+ ],
133
+ )
134
+
135
+ self.graphs_window = v.Window(
136
+ v_model="inputs",
137
+ children=[
138
+ v.WindowItem(
139
+ value="inputs",
140
+ children=[
141
+ v.Divider(),
142
+ v.Spacer(),
143
+ self.process_figures,
144
+ ],
145
+ ),
146
+ v.WindowItem(
147
+ value="outputs",
148
+ children=[
149
+ v.Divider(),
150
+ v.Spacer(),
151
+ self.output_figures,
152
+ ],
153
+ ),
154
+ ],
155
+ )
156
+
157
+ self.graphs = v.Container(
158
+ fluid=True,
159
+ children=[
160
+ self.graphs_tabs,
161
+ self.graphs_window,
162
+ ],
163
+ )
164
+
165
+ self.graphs_tabs.observe(
166
+ self._switch_tab,
167
+ names="v_model",
168
+ )
169
+
170
+ self.header = Header()
171
+ self.header.fast_oad_logo.on_event("click", lambda *args: self._to_tutorial())
172
+ self.header.open_drawer_button.on_event(
173
+ "click",
174
+ self._open_or_close_drawer,
175
+ )
176
+ self.header.clear_all_button.button.on_event(
177
+ "click",
178
+ self._clear_all_files,
179
+ )
180
+
181
+ self.drawer = Drawer()
182
+ self.drawer.close_drawer_button.on_event(
183
+ "click",
184
+ self._open_or_close_drawer,
185
+ )
186
+
187
+ self.footer = Footer()
188
+ self.footer.start_button.on_event("click", lambda *args: self._to_main())
189
+
190
+ self.to_outputs_button = v.Btn(
191
+ color="primary",
192
+ children=[
193
+ "Outputs",
194
+ v.Icon(class_="ps-2", children=["mdi-angle-right"]),
195
+ ],
196
+ )
197
+
198
+ self.to_inputs_button = v.Btn(
199
+ color="primary",
200
+ children=[
201
+ v.Icon(class_="pe-2", children=["mdi-angle-left"]),
202
+ "Inputs",
203
+ ],
204
+ )
205
+
206
+ self.navigation_buttons = v.Row(
207
+ class_="mx-6 mt-5",
208
+ )
209
+
210
+ # Padding column to avoid having the main content behind
211
+ # the drawer when expanded
212
+ self.padding_column = v.Col(
213
+ cols="1",
214
+ style_="padding: 100px 0 0 " + LEFT_PADDING + ";",
215
+ class_="hidden-md-and-down",
216
+ )
217
+
218
+ self.children = [
219
+ self.header,
220
+ self.drawer,
221
+ # Main content : to display graphs
222
+ v.Html(
223
+ tag="main",
224
+ class_="v-main",
225
+ children=[
226
+ v.Row(
227
+ style_="padding: " + TOP_PADDING + " 0 0 0;",
228
+ ),
229
+ v.Row(
230
+ no_gutters=True,
231
+ children=[
232
+ self.padding_column,
233
+ v.Col(
234
+ children=[
235
+ v.Row(
236
+ children=[
237
+ self.main_content,
238
+ ],
239
+ ),
240
+ ],
241
+ ),
242
+ ],
243
+ ),
244
+ ],
245
+ ),
246
+ self.footer,
247
+ ]
248
+
249
+ def _switch_process(self, change):
250
+ """
251
+ Switch display between MDA and MDO depending on process selection
252
+ button state.
253
+
254
+ To be called with "observe" method of a widget.
255
+ """
256
+ data = change["new"]
257
+
258
+ # If the button toggle is on 1, switch to MDO
259
+ if data == "MDO":
260
+ self.is_MDO = True
261
+ self.inputs.to_mdo()
262
+ self.process_figures.to_mdo()
263
+
264
+ else:
265
+ self.is_MDO = False
266
+ self.inputs.to_mda()
267
+ self.process_figures.to_mda()
268
+
269
+ def _to_process_computation(self):
270
+ """
271
+ When a process is on-going, blocks the inputs and set a loading screen.
272
+ """
273
+ self.inputs.disable()
274
+ for tab in self.graphs_tabs.children:
275
+ tab.disabled = True
276
+
277
+ # Show a loading widget to make it apparent that a computation is
278
+ # underway.
279
+ self.process_figures.set_loading("Setting up and running")
280
+
281
+ def _to_process_results(self):
282
+ """
283
+ Re-enables input widgets after the end of a MDA/MDO process.
284
+ """
285
+ self.inputs.enable()
286
+ for tab in self.graphs_tabs.children:
287
+ tab.disabled = False
288
+ if self.is_MDO:
289
+ snackbar_to_open = self.process_figures.mdo_end_snackbar
290
+ elif self.process_launcher.get_mda_success():
291
+ snackbar_to_open = self.process_figures.mda_success_snackbar
292
+ else:
293
+ snackbar_to_open = self.process_figures.mda_failure_snackbar
294
+ self.process_figures.open_snackbar(snackbar_to_open)
295
+ # This resets the view to what was displayed before the run was launched.
296
+ self.process_figures._change_display(
297
+ {"new": self.process_figures._display_selection_buttons.v_model}
298
+ )
299
+
300
+ def _launch_process(self, widget, event, data):
301
+ """
302
+ Retrieves the user inputs from the drawer and launch the selected
303
+ process.
304
+
305
+ To be called with "on_event" method of a widget.
306
+ """
307
+ self._to_process_computation()
308
+ if self.is_MDO:
309
+ self.inputs.retrieve_mdo_inputs()
310
+ else:
311
+ self.inputs.retrieve_mda_inputs()
312
+ self.process_launcher.launch_processes(is_mdo=self.is_MDO)
313
+ self._to_process_results()
314
+
315
+ def _set_source_data_file(self, change):
316
+ """
317
+ Sets the reference file name to use
318
+
319
+ To be called with "observe" method of a widget.
320
+ """
321
+ self.inputs.set_initial_value_mda(change["new"])
322
+
323
+ def _open_or_close_drawer(self, widget, event, data):
324
+ """
325
+ Opens or closes the input drawer depending on its actual state.
326
+
327
+ To be called with "on_event" method of a widget.
328
+ """
329
+ self.drawer.v_model = not self.drawer.v_model
330
+
331
+ def _clear_all_files(self, widget, event, data):
332
+ """
333
+ Clear all files contained in "workdir", in subdirectories "inputs"
334
+ and "outputs", that are not the files of the reference aircraft.
335
+ Also makes the user come back to source selection.
336
+
337
+ The subdirectories of workdir are not deleted in the process.
338
+ """
339
+ # Gets back to source file selection
340
+ self._to_tutorial()
341
+ # Clears the output selection
342
+ self.output_figures.output_selection.v_model = []
343
+ self.output_figures.hide_graphs()
344
+
345
+ PathManager.clear_all_files()