Source code for gemseo.scenarios.scenario_results.scenario_result

# 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.
"""Scenario result."""

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any
from typing import ClassVar
from typing import Final

from gemseo.algos.optimization_problem import OptimizationProblem
from gemseo.post.factory import PostFactory

if TYPE_CHECKING:
    from numpy import ndarray

    from gemseo import BasePost
    from gemseo.algos.optimization_result import OptimizationResult
    from gemseo.scenarios.base_scenario import BaseScenario


[docs] class ScenarioResult: """The result of a :class:`.Scenario`.""" _MAIN_PROBLEM_LABEL: Final[str] = "main" """The default label for the main problem.""" optimization_problems_to_results: dict[str, OptimizationResult] """The optimization results associated with the different optimization problems.""" design_variable_names_to_values: dict[str, ndarray] """The design variable names bound to the optimal values.""" __obj_to_be_post_processed: BaseScenario | OptimizationProblem """The object to be post-processed.""" _POST_FACTORY: ClassVar[PostFactory | None] = None """The factory of :class:`.BasePost`, if created.""" def __init__(self, scenario: BaseScenario | str | Path) -> None: """ Args: scenario: The scenario to post-process or the path to its HDF5 file. Raises: ValueError: When the scenario has not yet been executed. """ # noqa: D205 D212 D415 if isinstance(scenario, (str, Path)): self.__obj_to_be_post_processed = OptimizationProblem.from_hdf(scenario) optimization_result = self.__obj_to_be_post_processed.solution else: self.__obj_to_be_post_processed = scenario.formulation.optimization_problem optimization_result = scenario.optimization_result if optimization_result is None: msg = "A ScenarioResult requires a scenario that has been executed." raise ValueError(msg) self.design_variable_names_to_values = optimization_result.x_opt_as_dict self.optimization_problems_to_results = { self._MAIN_PROBLEM_LABEL: optimization_result } # TODO: API: the factory is a global object, remove this property. @classmethod @property def POST_FACTORY(cls) -> PostFactory: # noqa: N802 """The factory of post-processors.""" if cls._POST_FACTORY is None: cls._POST_FACTORY = PostFactory() return cls._POST_FACTORY @property def optimization_result(self) -> OptimizationResult: """The optimization result of the main optimization problem. For some scenarios, such as those based on multi-level formulations, there are several optimization problems including a main one. The current optimization result corresponds to this main optimization problem. For scenarios with a single optimization problem, the current optimization result corresponds to this unique optimization problem. """ return self.optimization_problems_to_results[self._MAIN_PROBLEM_LABEL]
[docs] def plot(self, name: str, **settings: Any) -> BasePost: """Visualize the result. Args: name: The name of the post-processing. **settings: The settings of the post-processing. Returns: The post-processing of the result. """ return self.POST_FACTORY.execute( self.__obj_to_be_post_processed, post_name=name, **settings )