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.