Skip to content

Integration of models

Integrate the models of interest 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

A GEMSEO discipline can be easily turned into a VIMSEO model, by deriving a class from BaseDisciplineModel and setting the _DISCIPLINE class attribute:

# Copyright 2021 IRT Saint Exupery, 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"

If you have a model defined as a Python code, the integration process to VIMSEO can be:

  • wrap this model in a GEMSEO discipline
  • use the above procedure to convert it as a VIMSEO model

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

If you have a model defined from Python code, and want to integrate it as a three-step pre-processing, run-processing and post-processing:

# Copyright 2021 IRT Saint Exupery, 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
# Copyright 2021 IRT Saint Exupery, 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 numpy import array
from numpy import atleast_1d

from vimseo.core.components.base_component import BaseComponent
from vimseo.problems.mock import X1_DEFAULT_VALUE


class MockPre(BaseComponent):
    """Mock Class for pre-processing."""

    USE_JOB_DIRECTORY = False


class MockPre_LC1(MockPre):
    """Mock Class for pre-processing with a load case."""

    def __init__(self, **options) -> None:
        super().__init__(**options)
        self.default_input_data.update({
            "x1": atleast_1d(X1_DEFAULT_VALUE),
            "x1_maximum_only": atleast_1d(X1_DEFAULT_VALUE),
            "x1_minimum_only": atleast_1d(X1_DEFAULT_VALUE),
            "x1_no_bounds": atleast_1d(X1_DEFAULT_VALUE),
        })

    def _run(self, input_data):
        x1 = input_data["x1"]
        x2 = x1 + 2
        return {"x2": x2}


class MockRun(BaseComponent):
    """Mock Class for run."""

    def _run(self, input_data):
        x2 = input_data["x2"]
        y0 = x2 * 2
        return {"y0": y0}


class MockPost(BaseComponent):
    """Mock Class for post-processing."""


class MockPost_LC1(MockPost):
    """Mock Class for post-processing with a loadcase."""

    def _run(self, input_data):
        y0 = input_data["y0"]
        y1 = y0 + 1
        return {"y1": y1, "error_code": array([0])}

If you also want to define a material for this model, you can look at the below example:

# Copyright 2021 IRT Saint Exupery, 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"

The material itself is defined from two files. Its grammar, possibly defining the bounds and types of the properties:

{
  "name": "OPFM_default_material",
  "required": [
    "E1"
  ],
  "properties": {
    "E1": {
      "description": "Longitudinal modulus (MPa)",
      "type": "array",
      "items": {
        "type": "number",
        "maximum": 190000.0,
        "minimum": 100000.0
      }
    }
  },
  "$schema": "http://json-schema.org/draft-04/schema",
  "type": "object",
  "id": "#OPFM_default_material"
}

and the values, possibly defining probability distributions for the properties:

{
  "name": "Mock",
  "description": "",
  "material_relations": [
    {
      "tag": "",
      "name": "DefaultMaterialRelation",
      "metadata": {
        "generic": {
          "datetime": "01-08-2024_18-51-58",
          "version": "vims_Dec2021_alpha"
        },
        "misc": {},
        "author": "",
        "source": ""
      },
      "properties": [
        {
          "name": "E1",
          "description": "",
          "value": 150000.0,
          "lower_bound": 100000.0,
          "upper_bound": 190000.0,
          "distribution": {
            "name": "",
            "mode": 0.0,
            "minimum": -1000000000000.0,
            "maximum": 1000000000000.0,
            "sigma": 0.0,
            "mu": 1.0,
            "lower_bound": 100000.0,
            "upper_bound": 190000.0,
            "parameters": []
          }
        }
      ]
    }
  ]
}

The input grammar and default input data are automatically filled with the material properties.