# Scalable diagonal discipline¶

Let us consider the SobieskiAerodynamics discipline. We want to build its ScalableDiscipline counterpart, using a ScalableDiagonalModel

For that, we can use a 20-length DiagonalDOE and test different sizes of variables or different settings for the scalable diagonal discipline.

from __future__ import absolute_import, division, unicode_literals

from future import standard_library


## Import¶

from gemseo.api import (
configure_logger,
create_discipline,
create_scalable,
create_scenario,
)
from gemseo.problems.sobieski.core import SobieskiProblem

configure_logger()

standard_library.install_aliases()


## Learning dataset¶

The first step is to build an AbstractFullCache dataset from a DiagonalDOE.

### Instantiate the discipline¶

For that, we instantiate the SobieskiAerodynamics discipline and set it up to cache all evaluations.

discipline = create_discipline("SobieskiAerodynamics")
discipline.set_cache_policy(discipline.MEMORY_FULL_CACHE)


### Get the input space¶

We also define the input space on which to sample the discipline.

input_space = SobieskiProblem().read_design_space()
input_space.filter(discipline.get_input_data_names())


Out:

<gemseo.algos.design_space.DesignSpace object at 0x7fc29db32ac0>


### Build the DOE scenario¶

Lastly, we sample the discipline by means of a DOEScenario relying on both discipline and input space. In order to build a diagonal scalable discipline, a DiagonalDOE must be used.

scenario = create_scenario(
[discipline], "DisciplinaryOpt", "y_2", input_space, scenario_type="DOE"
)
scenario.execute({"algo": "DiagonalDOE", "n_samples": 20})


Out:

{'eval_jac': False, 'algo': 'DiagonalDOE', 'n_samples': 20}


## Build the scalable discipline¶

The second step is to build a ScalableDiscipline, using a ScalableDiagonalModel and the cache of the discipline.

scalable = create_scalable("ScalableDiagonalModel", discipline.cache)


### Visualize the input-output dependencies¶

We can easily access the underlying ScalableDiagonalModel and plot the corresponding input-output dependency matrix where the level of gray and the number (in [0,100]) represent the degree of dependency between inputs and outputs. Input are on the left while outputs are at the top. More precisely, for a given output component located at the top of the graph, these degrees are contributions to the output component and they add up to 1. In other words, a degree expresses this contribution in percentage and for a given column, the elements add up to 100.

scalable.scalable_model.plot_dependency(save=False, show=True)


### Visualize the 1D interpolations¶

For every output, we can also visualize a spline interpolation of the output samples over the diagonal of the input space.

scalable.scalable_model.plot_1d_interpolations(save=False, show=True)


Out:

[]


## Increased problem dimension¶

We can repeat the construction of the scalable discipline for different sizes of variables and visualize the input-output dependency matrices.

### Twice as many inputs¶

For example, we can increase the size of each input by a factor of 2.

sizes = {
name: discipline.cache.varsizes[name] * 2
for name in discipline.get_input_data_names()
}
scalable = create_scalable("ScalableDiagonalModel", discipline.cache, sizes)
scalable.scalable_model.plot_dependency(save=False, show=True)


### Twice as many outputs¶

Or we can increase the size of each output by a factor of 2.

sizes = {
name: discipline.cache.varsizes[name] * 2
for name in discipline.get_output_data_names()
}
scalable = create_scalable("ScalableDiagonalModel", discipline.cache, sizes)
scalable.scalable_model.plot_dependency(save=False, show=True)


### Twice as many variables¶

Or we can increase the size of each input and each output by a factor of 2.

names = list(discipline.get_input_data_names())
names += list(discipline.get_output_data_names())
sizes = {name: discipline.cache.varsizes[name] * 2 for name in names}
scalable = create_scalable("ScalableDiagonalModel", discipline.cache, sizes)
scalable.scalable_model.plot_dependency(save=False, show=True)


## Binary IO dependencies¶

By default, any output component depends on any input component with a random level. We can also consider sparser input-output dependency by means of binary input-output dependency matrices. For that, we have to set the value of the fill factor which represents the part of connection between inputs and outputs. Then, a connection is represented by a black square while an absence of connection is presented by a white one. When the fill factor is equal to 1, any input is connected to any output. Conversely, when the fill factor is equal to 0, there is not a single connection between inputs and outputs.

### Fill factor = 0.2¶

Here, there is a 20% connection rate

scalable = create_scalable(
"ScalableDiagonalModel", discipline.cache, sizes, fill_factor=0.2
)
scalable.scalable_model.plot_dependency(save=False, show=True)


### Fill factor = 0.5¶

Here, there is a 50% connection rate

scalable = create_scalable(
"ScalableDiagonalModel", discipline.cache, sizes, fill_factor=0.5
)
scalable.scalable_model.plot_dependency(save=False, show=True)


### Fill factor = 0.8¶

Here, there is a 80% connection rate

scalable = create_scalable(
"ScalableDiagonalModel", discipline.cache, sizes, fill_factor=0.8
)
scalable.scalable_model.plot_dependency(save=False, show=True)


## Heterogeneous dependencies¶

We could also imagine a more complex situation where an output would depend inputs with a particular fill factor. For example, let us consider a 20% connection rate for "y_2".

scalable = create_scalable(
"ScalableDiagonalModel", discipline.cache, sizes, fill_factor={"y_2": 0.2}
)
scalable.scalable_model.plot_dependency(save=False, show=True)


## Group dependencies¶

We could also imagine another particular situation where an output would depend only on certain inputs. For example, let us suppose that "y_2" depends only on "x_shared".

scalable = create_scalable(
"ScalableDiagonalModel", discipline.cache, sizes, group_dep={"y_2": ["x_shared"]}
)
scalable.scalable_model.plot_dependency(save=False, show=True)


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

Gallery generated by Sphinx-Gallery