MultiFiMetaModelUnStructuredComp#

MultiFiMetaModelUnStructuredComp is a component that allows you to create a surrogate model where the training data has been gathered from sources with multiple levels of fidelity. This approach can be beneficial when a high-fidelity model is expensive to evaluate but a low-fidelity model exists that can be evaluated more efficiently at the cost of some accuracy; the main benefit comes from replacing some of the expensive evaluation points with a larger set of cheaper points while maintaining confidence in the overall prediction.

MultiFiMetaModelUnStructuredComp inherits from MetaModelUnStructuredComp, so its interface and usage are mostly the same. However, it does not use the same SurrogateModels. The only available SurrogateModel is the MultiFiCoKrigingSurrogate, which implements the Multi-Fidelity Co-Kriging method as found in Scikit-Learn.

MultiFiMetaModelUnStructuredComp Options#

OptionDefaultAcceptable ValuesAcceptable TypesDescription
always_optFalse[True, False]['bool']If True, force nonlinear operations on this component to be included in the optimization loop even if this component is not relevant to the design variables and responses.
default_surrogateN/AN/A['SurrogateModel', 'NoneType']Surrogate that will be used for all outputs that don't have a specific surrogate assigned to them.
distributedFalse[True, False]['bool']If True, set all variables in this component as distributed across multiple processes
nfi1N/A['int']Number of levels of fidelity.
run_root_onlyFalse[True, False]['bool']If True, call compute, compute_partials, linearize, apply_linear, apply_nonlinear, and compute_jacvec_product only on rank 0 and broadcast the results to the other ranks.
vec_size1N/A['int']Number of points that will be simultaneously predicted by the surrogate.

MultiFiMetaModelUnStructuredComp Constructor#

The call signature for the MultiFiMetaModelUnStructuredComp constructor is:

MultiFiMetaModelUnStructuredComp.__init__()[source]

Initialize all attributes.

Simple Example#

The following example shows a MultiFiMetaModelUnStructuredComp used to model the 2D Branin function, where the output is a function of two inputs, and we have pre-computed the training point location and values at a variety of points using models with two different fidelity levels. Adding an input or output named ‘x’ spawns entries in the “options” dictionary where the training data can be specified. The naming convention is ‘train_y’ for the highest fidelity, and ‘train_y_fi2’ for the lowest fidelity level (or in the case of more than 2 fidelity levels, the next highest level.)

import numpy as np
import openmdao.api as om

mm = om.MultiFiMetaModelUnStructuredComp(nfi=2)
mm.add_input('x', np.zeros((1, 2)))
mm.add_output('y', np.zeros((1, )))

# Surrrogate model that implements the multifidelity cokriging method.
mm.options['default_surrogate'] = om.MultiFiCoKrigingSurrogate(normalize=False)

prob = om.Problem()
prob.model.add_subsystem('mm', mm)

prob.setup()

x_hifi = np.array([[ 0.13073587,  0.24909577],  # expensive (hifi) doe
                   [ 0.91915571,  0.4735261 ],
                   [ 0.75830543,  0.13321705],
                   [ 0.51760477,  0.34594101],
                   [ 0.03531219,  0.77765831],
                   [ 0.27249206,  0.5306115 ],
                   [ 0.62762489,  0.65778471],
                   [ 0.3914706 ,  0.09852519],
                   [ 0.86565585,  0.85350002],
                   [ 0.40806563,  0.91465314]])

y_hifi = np.array([69.22687251161716,
                   28.427292491743817,
                   20.36175030334259,
                   7.840766670948326,
                   23.950783505007422,
                   16.0326610719367,
                   77.32264403894713,
                   26.625242780670835,
                   135.85615334210993,
                   101.43980212355875])

x_lofi = np.array([[ 0.91430235,  0.17029894],  # cheap (lowfi) doe
                   [ 0.99329651,  0.76431519],
                   [ 0.2012252 ,  0.35006032],
                   [ 0.61707854,  0.90210676],
                   [ 0.15113004,  0.0133355 ],
                   [ 0.07108082,  0.55344447],
                   [ 0.4483159 ,  0.52182902],
                   [ 0.5926638 ,  0.06595122],
                   [ 0.66305449,  0.48579608],
                   [ 0.47965045,  0.7407793 ],
                   [ 0.13073587,  0.24909577],  # notice hifi doe inclusion
                   [ 0.91915571,  0.4735261 ],
                   [ 0.75830543,  0.13321705],
                   [ 0.51760477,  0.34594101],
                   [ 0.03531219,  0.77765831],
                   [ 0.27249206,  0.5306115 ],
                   [ 0.62762489,  0.65778471],
                   [ 0.3914706 ,  0.09852519],
                   [ 0.86565585,  0.85350002],
                   [ 0.40806563,  0.91465314]])

y_lofi = list([18.204898470295255,
               107.66640600958577,
               46.11717344625053,
               186.002239934648,
               135.12480249921992,
               65.3605467926758,
               51.72316385370553,
               15.541873662737451,
               72.77648156410065,
               100.33324800434931,
               86.69974561161716,
               52.63307549174382,
               34.358261803342586,
               28.218996970948325,
               57.280532805007425,
               41.9510060719367,
               107.05618533894713,
               39.580998480670836,
               171.46115394210995,
               138.87939632355875])

mm.options['train_x'] = x_hifi
mm.options['train_y'] = y_hifi
mm.options['train_x_fi2'] = x_lofi
mm.options['train_y_fi2'] = y_lofi

prob.set_val('mm.x', np.array([[2./3., 1./3.]]))
prob.run_model()

print(prob.get_val('mm.y'))
[26.26682506]
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/openmdao/components/meta_model_unstructured_comp.py:306: DerivativesWarning:Because the MetaModelUnStructuredComp 'mm' uses a surrogate which does not define a linearize method,
OpenMDAO will use finite differences to compute derivatives. Some of the derivatives will be computed
using default finite difference options because they were not explicitly declared.
The derivatives computed using the defaults are:
    mm.y, mm.x