# Use simFunction in an Optimization

Often, the analysis is not a simple quasistatic or transient analysis. The run may contain several simulations. In between simulations entities may be modified or even activated/deactivated. All of this may be managed by sophisticated event driven logic. How can we optimize a model like this?

The answer is to use simFunction in the optimizer to define the analysis script. simFunction is a user subroutine that allows you to run any combination of MotionSolve commands within any logic that you need. When SimFunction is specified, the Optimizer will invoke the SimFunction whenever it needs to evaluate the cost or the sensitivity.

Here are some general rules to follow when writing a simFunction

## Only one argument: model

simFunction has only one argument: the model. Inside SimFunction, you can use the model object to invoke simulations and access or modify model data.

## Suppress output during simulation

You might want to suppress the output during the simulation. Otherwise, too much information will be printed out during the optimization. You can suppress the output by setting output=’Off’; however, this is not mandatory.

## Revert model changes to bring it back to its initial definition

Make sure to revert any changes before returning the result in simFunction. The model should be identical for each separate run, so it should be reset to its original stage. For example, if you change the mass of part1 from 3kg to 5kg before the last run, you need to reset the mass to be 3kg after it.

An example following all the rules is given here:

def simulate_function_pid(model):

# Perform initial static
run = model.simulate (type=’STATICS’, returnResults=True, output=’Off’)

# Initial dynamic run to reach desired configuration
run = model.simulate (type=’DYNAMICS’, end=10, dtout=0.01, dsa='NONE',
returnResults=True, output=’Off’)

# Activate the damper force
model.damper.active = False

# Now perform a dynamic run, with DSA turned on
run = model.simulate (type=’DYNAMICS’, end=100, dtout=0.01, dsa='AUTO',
returnResults=True, output=’Off’)

# Return model back to original topology
model.force.active = True

# Return the results for live processing
return run