Source code for gemseo_fmu.problems.disciplines.sellar.sellar_system
# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 3 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Contributors:
# INITIAL AUTHORS - API and implementation and/or documentation
# :author: Jorge Camacho
# OTHER AUTHORS - MACROSCOPIC CHANGES
"""The system discipline of the Sellar use case."""
from __future__ import annotations
from cmath import exp
from typing import Iterable
from numpy import array
from numpy import ndarray
from numpy import ones
from gemseo_fmu.disciplines.fmu_discipline import FMUDiscipline
from gemseo_fmu.problems.disciplines.sellar.variable_names import C_1
from gemseo_fmu.problems.disciplines.sellar.variable_names import C_2
from gemseo_fmu.problems.disciplines.sellar.variable_names import OBJ
from gemseo_fmu.problems.disciplines.sellar.variable_names import X_LOCAL
from gemseo_fmu.problems.disciplines.sellar.variable_names import X_SHARED_2
from gemseo_fmu.problems.disciplines.sellar.variable_names import Y_1
from gemseo_fmu.problems.disciplines.sellar.variable_names import Y_2
from gemseo_fmu.problems.fmu_files import get_fmu_file_path
[docs]class FMUSellarSystem(FMUDiscipline):
"""The discipline to compute the objective and constraints of the Sellar problem."""
def __init__(self) -> None: # noqa: D107
super().__init__(
get_fmu_file_path("SellarSystem", "sellar"),
initial_time=0.0,
final_time=0.0,
add_time_to_output_grammar=False,
)
[docs] @staticmethod
def compute_obj(
x_local: ndarray,
x_shared: ndarray,
y_1: ndarray,
y_2: ndarray,
) -> float:
"""Evaluate the objective :math:`obj`.
Args:
x_local: The design variables local to the first discipline.
x_shared: The shared design variables.
y_1: The coupling variable coming from the first discipline.
y_2: The coupling variable coming from the second discipline.
Returns:
The value of the objective :math:`obj`.
"""
return x_local[0] ** 2 + x_shared[1] + y_1[0] ** 2 + exp(-y_2[0])
[docs] @staticmethod
def compute_c_1(
y_1: ndarray,
) -> float:
"""Evaluate the constraint :math:`c_1`.
Args:
y_1: The coupling variable coming from the first discipline.
Returns:
The value of the constraint :math:`c_1`.
"""
return 3.16 - y_1[0] ** 2
[docs] @staticmethod
def compute_c_2(
y_2: ndarray,
) -> float:
"""Evaluate the constraint :math:`c_2`.
Args:
y_2: The coupling variable coming from the second discipline.
Returns:
The value of the constraint :math:`c_2`.
"""
return y_2[0] - 24.0
def _compute_jacobian(
self,
inputs: Iterable[str] | None = None,
outputs: Iterable[str] | None = None,
) -> None:
self._init_jacobian(inputs, outputs)
x_local, y_1, y_2 = self.get_inputs_by_name([X_LOCAL, Y_1, Y_2])
y_10 = y_1[0]
self.jac[C_1][Y_1] = array([[-2.0 * y_10]])
self.jac[C_2][Y_2] = ones((1, 1))
self.jac[OBJ] = {
X_LOCAL: array([[2.0 * x_local[0]]]),
X_SHARED_2: ones((1, 1)),
Y_1: array([[2.0 * y_10]]),
Y_2: array([[-exp(-y_2[0])]]),
}