Source code for gemseo.formulations.base_mdo_formulation

# 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 - initial API and implementation and/or initial
#                         documentation
#        :author: Francois Gallard
#    OTHER AUTHORS   - MACROSCOPIC CHANGES
"""The base class for all MDO formulations."""

from __future__ import annotations

from typing import TYPE_CHECKING

from numpy import zeros

from gemseo.core.mdo_functions.function_from_discipline import FunctionFromDiscipline
from gemseo.core.mdo_functions.mdo_function import MDOFunction
from gemseo.core.mdo_functions.taylor_polynomials import compute_linear_approximation
from gemseo.formulations.base_formulation import BaseFormulation
from gemseo.utils.string_tools import convert_strings_to_iterable

if TYPE_CHECKING:
    from collections.abc import Sequence

    from gemseo.core.discipline.discipline import Discipline


[docs] class BaseMDOFormulation(BaseFormulation): """A base class for MDO formulations."""
[docs] def add_observable( # noqa: D102 self, output_names: str | Sequence[str], observable_name: str = "", discipline: Discipline | None = None, ) -> None: if isinstance(output_names, str): output_names = [output_names] obs_fun = FunctionFromDiscipline(output_names, self, discipline=discipline) if observable_name: obs_fun.name = observable_name self.optimization_problem.add_observable(obs_fun)
[docs] def add_constraint( # noqa: D102 self, output_name: str | Sequence[str], constraint_type: MDOFunction.ConstraintType = MDOFunction.ConstraintType.EQ, constraint_name: str = "", value: float = 0, positive: bool = False, ) -> None: output_names = convert_strings_to_iterable(output_name) constraint = FunctionFromDiscipline(output_names, self) if constraint.discipline_adapter.is_linear: constraint = compute_linear_approximation( constraint, zeros(constraint.discipline_adapter.input_dimension) ) constraint.f_type = constraint_type if constraint_name: constraint.name = constraint_name constraint.has_default_name = False else: constraint.has_default_name = True self.optimization_problem.add_constraint( constraint, value=value, positive=positive )