Note

Go to the end to download the full example code

# MDA residuals¶

This example illustrates how to retrieve the normed residual of a given MDA.

The residual of an MDA is a vector defined by \(\mathrm{couplings}_k - \mathrm{couplings}_{k+1}\), where \(k\) and \(k+1\) are two successive iterations of the MDA algorithm and \(\mathrm{couplings}\) is the coupling vector.

The normed residual is the normalized value of \(\norm{\mathrm{residuals}}\). When the normed residual is smaller than a given tolerance value, the MDA has converged. It is a simple way to quantify the MDA convergence.

This normed residual can be seen as an MDA output. Therefore, it can be used as a constraint in an MDO scenario, or can simply be retrieved as a scenario observable. It is a simple way to determine whether a given solution has a feasible design (MDA convergence) or not.

```
from __future__ import annotations
from gemseo import configure_logger
from gemseo import create_discipline
from gemseo import create_mda
configure_logger()
```

```
<RootLogger root (INFO)>
```

## Create and execute the MDA¶

We do not need to specify the inputs, the default inputs
of the `MDA`

will be used and computed from the
default inputs of the disciplines.

Here, we could have replaced `MDAGaussSeidel`

by any other MDA.

```
disciplines = create_discipline([
"SobieskiStructure",
"SobieskiPropulsion",
"SobieskiAerodynamics",
"SobieskiMission",
])
mda = create_mda("MDAGaussSeidel", disciplines)
output_data = mda.execute()
```

## MDA convergence analysis¶

The MDA algorithm will stop if one of the following criteria is fulfilled:

The normed residual is lower than the MDA tolerance. This case appears when the design is feasible.

The maximal number of iterations is reached. In that case, the design is not feasible.

The normed residual can be seen by the `MDA`

attribute `normed_residual`

.

```
mda.normed_residual
```

```
5.50839275306244e-07
```

The evolution of its value can be plotted with `plot_residual_history()`

,
or accessed by `residual_history`

.

When an MDA is called more than once (by a DOE driver for instance),
the `residual_history`

stores the different values of the normed residual
in a single list.

```
residual_history = mda.residual_history
residual_history
```

```
[1.0, 0.709008476835191, 0.09279601629441475, 0.012492524096475305, 0.0016808042405903614, 0.0002261485507646748, 3.0427816889922925e-05, 4.0940000680510455e-06, 5.50839275306244e-07]
```

The normed MDA residual can be seen as an MDA output,
just like the couplings.
To get the normed MDA residual,
the key registered by `RESIDUALS_NORM`

(`""MDA residuals norm"`

) can be used.

```
f"The normed residual key is: {mda.RESIDUALS_NORM}."
```

```
'The normed residual key is: MDA residuals norm.'
```

This normed residual can be used as a constraint in an MDO scenario, or can simply be retrieved as a scenario observable.

```
normed_residual = output_data[mda.RESIDUALS_NORM]
normed_residual
```

```
array([5.50839275e-07])
```

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