Skip to content

Integration of models

Integrate the model of interests is the first mandatory step before using the VV&UQ methods of VIMSEO. As a result, VIMSEO should make model integration as easy as possible, and provide a range of examples to illustrate different ways of integrating models.

VIMSEO follows a component-based approach for model integration. A model contains a list of executable components, which are run sequentially. To learn more about the advantages of this approach, you can refer to model integration explanation

Integration of a GEMSEO discipline

# 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.

"""A model in asymptotic convergence by construction.

Notations are taken from:
https://asmedigitalcollection.asme.org/verification/article/7/3/031005/1146443/Confidence-Intervals-for-Richardson-Extrapolation
"""

from __future__ import annotations

from gemseo.disciplines.analytic import AnalyticDiscipline
from numpy import atleast_1d

from vimseo.core.base_discipline_model import BaseDisciplineModel
from vimseo.core.model_metadata import MetaDataNames

ORDER = 2
mock_convergence_discipline = AnalyticDiscipline({
    "a_h": "a - a_n * h**n - a_m * h**m",
    "n_dof": "1. / h**3",
    MetaDataNames.cpu_time.name: "1.0",
})
mock_convergence_discipline.default_input_data = {
    "a": atleast_1d(1.0),
    "a_n": atleast_1d(0.1),
    "h": atleast_1d(2),
    "n": atleast_1d(ORDER),
    "a_m": atleast_1d(0.0),
    "m": atleast_1d(ORDER + 1),
}


class MockConvergence(BaseDisciplineModel):
    _DISCIPLINE = mock_convergence_discipline
    _EXPECTED_LOAD_CASE = "Dummy"

Integration of a pure Python model as a single component model

Here, model MockModelFields defines the variable FIELDS_FROM_FILE, which means that files corresponding to this pattern are expected to be written by the model in the scrtch directory.

# 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.

from __future__ import annotations

from shutil import copy
from typing import TYPE_CHECKING
from typing import ClassVar

from numpy import atleast_1d

from vimseo.core.base_component import BaseComponent
from vimseo.core.base_integrated_model import IntegratedModel
from vimseo.core.components.component_factory import ComponentFactory
from vimseo.core.model_settings import IntegratedModelSettings
from vimseo.problems.mock.mock_fields.fields import MOCK_FIELDS_DIR

if TYPE_CHECKING:
    from collections.abc import Mapping
    from collections.abc import Sequence
    from pathlib import Path


class MockComponentField_LC1(BaseComponent):
    """Standalone component for MockModelField."""

    USE_JOB_DIRECTORY = True
    auto_detect_grammar_files = False

    FILES_TO_COPY: ClassVar[Sequence[Path | str]] = ["Pyramid.vtk"]

    def __init__(self, load_case_name: str):
        super().__init__(load_case_name)
        self.__default_inputs = {
            "x1": atleast_1d(2.0),
        }
        self.input_grammar.update_from_data(self.__default_inputs)
        self.output_grammar.update_from_data({
            "y1": atleast_1d(0.0),
            "error_code": atleast_1d(0),
        })
        self.default_input_data.update(self.__default_inputs)

    def _run(self, input_data):
        for file_name in self.FILES_TO_COPY:
            copy(MOCK_FIELDS_DIR / file_name, self.job_directory)
        return {"y1": input_data["x1"], "error_code": atleast_1d([0])}


class MockModelFields(IntegratedModel):
    """Mock model handling Field files."""

    FIELDS_FROM_FILE: ClassVar[Mapping[str, str]] = {"pyramid": r"^Pyramid\.vtk$"}

    def __init__(self, load_case_name: str, **options):
        options = IntegratedModelSettings(**options).model_dump()
        super().__init__(
            load_case_name,
            [
                ComponentFactory().create(
                    "MockComponentField",
                    load_case_name,
                )
            ],
            **options,
        )

Integration of a pure Python model as a pre-run-post component model

# 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.

from __future__ import annotations

from vimseo.core.pre_run_post_model import PreRunPostModel


class MockModel(PreRunPostModel):
    """Mock Class to test the creation of a model."""

    SUMMARY = (
        " A toy model implementing an unphysical analytical law;"
        " used for testing purpose"
    )
    PRE_PROC_FAMILY = "MockPre"  # x2 = x1 + 2
    RUN_FAMILY = "MockRun"  # y0 = x2 * 2
    POST_PROC_FAMILY = "MockPost"  # y1 = y0 + 1

And a second example where a material is defined. The input grammar and default input data are automatically filled with the material properties.

# 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.

from __future__ import annotations

from vimseo.material_lib import MATERIAL_LIB_DIR
from vimseo.problems.mock.mock_pre_run_post.mock_main import MockModel


class MockModelWithMaterial(MockModel):
    """Mock model to test loading of a material file."""

    SUMMARY = "A toy model loading a material"
    _MATERIAL_GRAMMAR_FILE = MATERIAL_LIB_DIR / "Mock_grammar.json"
    MATERIAL_FILE = MATERIAL_LIB_DIR / "Mock.json"