Open japaf opened 9 years ago
Yes, this has become MUCH easier with v0.5 since the core interface library is now loadable from python AND C. Just call the callModel function on SurrogateModel
inputs = {'a': 1; 'b': 2}
model=SurrogateModel.load('modelName')
outputs=model.callModel(inputs)
If you want to provide your own parameters, then you need to go little further down and do
inputs = {'a': 1; 'b': 2}
model=SurrogateModel.load('modelName')
cModel = modena.libmodena.modena_model_t(
model=model,
parameters=list(parameters)
)
in_i = list()
i = [0] * (1 + model.inputs_max_argPos())
for k, v in model.inputs.iteritems():
i[v.argPos] = inputs[k]
outputs=cModel.call(in_i, i, checkBounds=False)
Note: You should not need to do this by hand. This case should be handled by the framework! But if this is really needed, I can provide an optional parameter argument option on callModel.
Thanks, this really is quite simple. As far as model fitting is concerned, I see this as only temporary solution.
I had to make a few adjustments, because model.inputs is MinMaxOpt object and doesn't have argPos key. Following code works for me:
inputs = {'a': 1, 'b': 2}
model=SurrogateModel.load('modelName')
cModel = modena.libmodena.modena_model_t(
model=model,
parameters=list(parameters)
)
in_i = list()
i = [0] * (1 + model.inputs_max_argPos())
for k, v in inputs.iteritems():
i[model.inputs_argPos(k)] = inputs[k]
outputs=cModel.call(in_i, i, checkBounds=False)
Just to put it into perspective, take look at a minimal working example:
Import modena modules
from modena import ForwardMappingModel, SurrogateModel, CFunction, libmodena
from fireworks import Firework, Workflow, LaunchPad
from fireworks.core.rocket_launcher import rapidfire
Define a surrogate function.
NOTE:
If following (long) error message starting along the lines of By not providing "FindMODENA.cmake" in CMAKE_MODULE_PATH this project has
occurs, set the following environment variable: export CMAKE_PREFIX_PATH=${HOME}
.
r = CFunction(
Ccode= '''
#include "modena.h"
#include "math.h"
void idealGas
(
const double* parameters,
const double* inherited_inputs,
const double* inputs,
double *outputs
)
{
const double p0 = inputs[0];
const double T0 = inputs[1];
const double R = parameters[0];
outputs[0] = p0/R/T0;
}
''',
# These are global bounds for the function
inputs={
'p0': { 'min': 0, 'max': 9e99, 'argPos': 0 },
'T0': { 'min': 0, 'max': 9e99, 'argPos': 1 },
},
outputs={
'rho0': { 'min': 9e99, 'max': -9e99, 'argPos': 0 },
},
parameters={
'R': { 'min': 0.0, 'max': 9e99, 'argPos': 0 }
},
)
Define a forward mapping model. A backward mapping model requires more inputs, but they are a member of the same base class (surrogateModel).
m1 = ForwardMappingModel(
_id= 'idealGas',
surrogateFunction= r,
substituteModels= [ ],
parameters= [ 287.0 ],
inputs={
'p0': { 'min': 0, 'max': 9e99 },
'T0': { 'min': 0, 'max': 9e99 },
},
outputs={
'rho0': {'min': 0, 'max': 9e99 },
},
)
Initiate all surrogate models that have been defined using fireworks:
# set up the LaunchPad and reset it
launchpad = LaunchPad()
launchpad.reset('', require_password=False)
initFws = []
for m in SurrogateModel.get_instances():
initFws.append(m.initialisationFw())
# store workflow and launch it locally
launchpad.add_wf(Workflow(initFws, {}, name="initialisation"))
rapidfire(launchpad)
Finally, call the surrogate model as the question was answered:
inputs = {'T0': 298, 'p0': 10000} # inputs key:val (argument position is arbitrary)
model=SurrogateModel.load('idealGas') # load model from database
cModel = modena.libmodena.modena_model_t(
model=model
)
in_i = list() # empty list
i = [0] * (1 + model.inputs_max_argPos()) # input vector
for k, v in inputs.iteritems(): # iterate over keys in input
i[model.inputs_argPos(k)] = inputs[k] # Place inputs in the correct position in 'input vector'
out=cModel.call(in_i, i, checkBounds=False) # call model to perform calculation
outputs = { key: out[val.argPos] for key, val in model.surrogateFunction.outputs.iteritems() }
print outputs
In the early version of Modena interface it was possible to call C function compiled in the database from python using pymodena.modena_function_call(). It was used to determine fitting parameters of a surrogate model in python if we had precalculated data from detailed model or just to compare results of surrogate and detailed model in a plot. As far as I know, there is no easy alternative now. Possible workaround is to just define python function and copy (and translate to python) the algorithm from C function of surrogate model into this python function. This is neither elegant nor convenient.