Multi-point computations using namespaces#

from __future__ import annotations

from gemseo import create_design_space
from gemseo import create_discipline
from gemseo import create_scenario

About namespaces#

Namespaces are prefixes to input or output names of the disciplines. The name of a variable can be prefixed by the namespace and a separator, ":" by default. This allows to control the coupling of disciplines, or to duplicate a discipline in a process.

Instantiate the disciplines#

We instantiate twice the same discipline, they will be configured with the namespaces to compute different outputs. Some inputs will be shared, without namespace, and others will have different namespaces.

disciplines = create_discipline(["SobieskiMission", "SobieskiMission"])

Setting the namespaces#

In the SSBJ test case, the y_34 vector is the engine Specific Fuel Consumption (SFC). Let's say that we want to compute the average range of the aircraft, operating at two different operating conditions (oc1 and oc2), which leads to two different SFC. We add the specific namespaces to the SFC (y_34) of the disciplines, and to the output range (y_4) The other inputs of the discipline remain the same, so they share their values.

disciplines[0].input_grammar.add_namespace("y_34", "oc1")
disciplines[1].input_grammar.add_namespace("y_34", "oc2")

disciplines[0].output_grammar.add_namespace("y_4", "oc1")
disciplines[1].output_grammar.add_namespace("y_4", "oc2")

Averaging the outputs#

Then we need to create a specific discipline to average the outputs. We use the LinearCombination discipline for that. Note that the namespaces can be set by the input name directly.

disciplines.append(
    create_discipline(
        "LinearCombination",
        input_names=["oc1:y_4", "oc2:y_4"],
        output_name="average_y_4",
        input_coefficients={"oc1:y_4": 0.5, "oc2:y_4": 0.5},
    )
)

Build, execute and post-process the scenario#

In the design space, we add the two variables that are namespaced, and simulate several SFCs. The other variables remain at their default input's values.

design_space = create_design_space()
design_space.add_variable("oc1:y_34", lower_bound=0.8, upper_bound=2.0)
design_space.add_variable("oc2:y_34", lower_bound=0.8, upper_bound=2.0)

Instantiate the scenario#

The objective is the averaged range.

scenario = create_scenario(
    disciplines,
    formulation_name="MDF",
    objective_name="average_y_4",
    design_space=design_space,
    maximize_objective=True,
    scenario_type="DOE",
)

Visualize the XDSM#

The XDSM shows well the averaging proces and the duplication of the disciplines as well as the data handling

scenario.xdsmize(save_html=False)

scenario.execute(n_samples=20, algo_name="LHS")
INFO - 16:25:57: *** Start DOEScenario execution ***
INFO - 16:25:57: DOEScenario
INFO - 16:25:57:    Disciplines: LinearCombination SobieskiMission SobieskiMission
INFO - 16:25:57:    MDO formulation: MDF
INFO - 16:25:57: Optimization problem:
INFO - 16:25:57:    minimize -average_y_4(oc1:y_34, oc2:y_34)
INFO - 16:25:57:    with respect to oc1:y_34, oc2:y_34
INFO - 16:25:57:    over the design space:
INFO - 16:25:57:       +----------+-------------+-------+-------------+-------+
INFO - 16:25:57:       | Name     | Lower bound | Value | Upper bound | Type  |
INFO - 16:25:57:       +----------+-------------+-------+-------------+-------+
INFO - 16:25:57:       | oc1:y_34 |     0.8     |  None |      2      | float |
INFO - 16:25:57:       | oc2:y_34 |     0.8     |  None |      2      | float |
INFO - 16:25:57:       +----------+-------------+-------+-------------+-------+
INFO - 16:25:57: Solving optimization problem with algorithm LHS:
INFO - 16:25:57:      5%|▌         | 1/20 [00:00<00:00, 174.40 it/sec, feas=True, obj=-437]
INFO - 16:25:57:     10%|█         | 2/20 [00:00<00:00, 313.53 it/sec, feas=True, obj=-540]
INFO - 16:25:57:     15%|█▌        | 3/20 [00:00<00:00, 430.46 it/sec, feas=True, obj=-342]
INFO - 16:25:57:     20%|██        | 4/20 [00:00<00:00, 530.57 it/sec, feas=True, obj=-561]
INFO - 16:25:57:     25%|██▌       | 5/20 [00:00<00:00, 619.89 it/sec, feas=True, obj=-422]
INFO - 16:25:57:     30%|███       | 6/20 [00:00<00:00, 697.02 it/sec, feas=True, obj=-394]
INFO - 16:25:57:     35%|███▌      | 7/20 [00:00<00:00, 766.60 it/sec, feas=True, obj=-332]
INFO - 16:25:57:     40%|████      | 8/20 [00:00<00:00, 827.61 it/sec, feas=True, obj=-450]
INFO - 16:25:57:     45%|████▌     | 9/20 [00:00<00:00, 884.02 it/sec, feas=True, obj=-496]
INFO - 16:25:57:     50%|█████     | 10/20 [00:00<00:00, 932.96 it/sec, feas=True, obj=-535]
INFO - 16:25:57:     55%|█████▌    | 11/20 [00:00<00:00, 977.88 it/sec, feas=True, obj=-359]
INFO - 16:25:57:     60%|██████    | 12/20 [00:00<00:00, 1017.95 it/sec, feas=True, obj=-679]
INFO - 16:25:57:     65%|██████▌   | 13/20 [00:00<00:00, 1056.87 it/sec, feas=True, obj=-452]
INFO - 16:25:57:     70%|███████   | 14/20 [00:00<00:00, 1091.37 it/sec, feas=True, obj=-390]
INFO - 16:25:57:     75%|███████▌  | 15/20 [00:00<00:00, 1125.46 it/sec, feas=True, obj=-307]
INFO - 16:25:57:     80%|████████  | 16/20 [00:00<00:00, 1155.44 it/sec, feas=True, obj=-451]
INFO - 16:25:57:     85%|████████▌ | 17/20 [00:00<00:00, 1174.00 it/sec, feas=True, obj=-370]
INFO - 16:25:57:     90%|█████████ | 18/20 [00:00<00:00, 1197.61 it/sec, feas=True, obj=-492]
INFO - 16:25:57:     95%|█████████▌| 19/20 [00:00<00:00, 1219.87 it/sec, feas=True, obj=-373]
INFO - 16:25:57:    100%|██████████| 20/20 [00:00<00:00, 1236.31 it/sec, feas=True, obj=-679]
INFO - 16:25:57: Optimization result:
INFO - 16:25:57:    Optimizer info:
INFO - 16:25:57:       Status: None
INFO - 16:25:57:       Message: None
INFO - 16:25:57:    Solution:
INFO - 16:25:57:       Objective: -679.194677915797
INFO - 16:25:57:       Design space:
INFO - 16:25:57:          +----------+-------------+--------------------+-------------+-------+
INFO - 16:25:57:          | Name     | Lower bound |       Value        | Upper bound | Type  |
INFO - 16:25:57:          +----------+-------------+--------------------+-------------+-------+
INFO - 16:25:57:          | oc1:y_34 |     0.8     | 0.830888541534102  |      2      | float |
INFO - 16:25:57:          | oc2:y_34 |     0.8     | 0.9211557680119258 |      2      | float |
INFO - 16:25:57:          +----------+-------------+--------------------+-------------+-------+
INFO - 16:25:57: *** End DOEScenario execution (time: 0:00:00.018701) ***

Plot the optimization history view#

scenario.post_process(post_name="OptHistoryView", save=False, show=True)
  • Evolution of the optimization variables
  • Evolution of the objective value
  • Evolution of the distance to the optimum
<gemseo.post.opt_history_view.OptHistoryView object at 0x72a4d9bbbf80>

Total running time of the script: (0 minutes 0.277 seconds)

Gallery generated by Sphinx-Gallery