amisc
Efficient framework for building surrogates of multidisciplinary systems using the adaptive multi-index stochastic collocation (AMISC) technique.
- Author - Joshua Eckels (eckelsjd@umich.edu)
- License - GPL-3.0
The amisc
package takes an object-oriented approach to building a surrogate of a multidisciplinary system. From the
bottom up, you have:
- variables that serve as inputs and outputs for the models,
- interpolators that define a specific input → output mathematical relationship to interpolate a function,
- components that wrap a model for a single discipline, and a
- system that defines the connections between components in a multidisciplinary system.
The variables, interpolators, and components all have abstract base classes, so that the system is ultimately
independent of the specific models, interpolation methods, or underlying variables. As such, the primary top-level
object that users of the amisc
package will interact with is the SystemSurrogate
.
Note
There are already pretty good implementations of the other abstractions that most users will not need to worry about, but they are provided in this API reference for completeness. The abstractions allow new interpolation (i.e. function approximation) methods to be implemented if desired, such as neural networks, kriging, etc.
Here is a class diagram summary of this workflow:
classDiagram
namespace Core {
class SystemSurrogate {
+list[BaseRV] exo_vars
+list[BaseRV] coupling_vars
+int refine_level
+fit()
+predict(x)
+sample_inputs(size)
+insert_component(comp)
}
class ComponentSurrogate {
<<abstract>>
+IndexSet index_set
+IndexSet candidate_set
+list[BaseRV] x_vars
+dict[str: BaseInterpolator] surrogates
+dict[str: float] misc_coeff
+predict(x)
+activate_index(alpha, beta)
+add_surrogate(alpha, beta)
+update_misc_coeff()
}
class BaseInterpolator {
<<abstract>>
+tuple beta
+list[BaseRV] x_vars
+np.ndarray xi
+np.ndarray yi
+set_yi()
+refine()
+__call__(x)
}
}
class SparseGridSurrogate {
+np.ndarray x_grids
+dict xi_map
+dict yi_map
+get_tensor_grid(alpha, beta)
}
class LagrangeInterpolator {
+np.ndarray x_grids
+np.ndarray weights
+get_grid_sizes()
+leja_1d()
}
class BaseRV {
<<abstract>>
+tuple bounds
+str units
+float nominal
+pdf(x)
+sample(size)
}
class UniformRV {
+str type
+get_uniform_bounds(nominal)
}
SystemSurrogate o-- "1..n" ComponentSurrogate
ComponentSurrogate o-- "1..n" BaseInterpolator
direction LR
ComponentSurrogate <|-- SparseGridSurrogate
BaseInterpolator <|-- LagrangeInterpolator
SparseGridSurrogate ..> LagrangeInterpolator
BaseRV <|-- UniformRV
Note how the SystemSurrogate
aggregates the ComponentSurrogate
, which aggregates the BaseInterpolator
. In other
words, interpolators can act independently of components, and components can act independently of systems. All three
make use of the random variables (these connections and some RVs are not shown for visual clarity). Currently, the only
underlying surrogate method that is implemented here is Lagrange polynomial interpolation (i.e. the
LagrangeInterpolator
). If one wanted to use neural networks instead, the only change required is a new
implementation of BaseInterpolator
.