A recurring task in modeling is to set default values. There are several ways to do that, let’s clear up what they are and when to use them:
- Component Order (Domain order)
- Search Strategy
- Soft Function (a.k.a. Soft Default)
- Default Value (a.k.a. Hard Default)
Components closer to the top will be preferred before those further down. (This is really due to the default search strategy, nonetheless it is a useful trick to use.) By rearranging the components, you can influence what component will be prioritized: All other things equeal – in the left case “vbrakes” will be selected before “disc_brakes”, in the right case “disc_brakes” will be preferred. Use it: for simple default behaviors. *Component order is really just a special case of “domain order”, but a very common and useful case. See end of blog post for an overview of the domain order for the other domains.
Try in a search strategy you can ask the engine to set a specific value. If the value is not allowed because of other constraints or choices that the user has made, the engine will just ignore that action and move on to the next one. Search strategy actions are prioritized from to top to bottom. Want to change the order? Just drag the actions around (dragging works since TCstudio 4.5, in previous versions you can use the arrows next to the editor field). Two
Try actions to set front brake type and drive train type. Use it: to have full control of the default values. Also see Sebastian Dahlin’s blog post Search Strategy Default Values Using “Call” and “If”.
Search Strategies + Help Variable
Sometimes you want the default value to depend on another field or on some calculation, but the “Try” action can only set a fixed value. To solve this you can introduce a help variable that turns a constraint on or off, where the constraint is used to set the actual default value. An example: Our search strategy will try to set the help attribute “opt_brakesDifferent” to “No”… …which will succeed only if it is possible to set the front and back brakes to the same type. If not, the configuration engine will continue as if nothing happened. Tip: Name your help attribute so that answering “No” will give you the desired default value. In our case we used “opt_brakesDifferent” instead of “opt_sameBrakeType”), as “No” is the default Boolean value.
Soft Function (
A soft function means the engine will try to assign the value specified, but if it can’t it’ll just move on and not cause any trouble. In this way a soft function is very much like a Try in a search strategy, with two big differences:
- You have very little control over the order.
- You can use very flexible expressions to assign a value (conditional values, calculations etc.)
A simple example of a soft function setting a default value (rear brake type is defaulted to V-brakes). Use it: for models with few default values that won’t conflict with each other (or where their individual order doesn’t matter), or for quick tests of new default values. Also see the “Performance” section below. Note: Function atributes/features that are not assigned in any other way need to be set using a soft function (
~=) or a hard function (
:=, the equivalent of a
= but for function attributes/features), otherwise the engine won’t know what value to assign to the function and will refuse to start. Also, in some cases where the function attributes/features are part of complicated calculations, setting a default value for them will help the engine find a solution faster.
The “Default Value” checkbox (a.k.a. “Hard Default”) doesn’t just set a default value – it also commits the value. This means that the value can only change if the user changes it OR if there is a conflict with another value and the engines asks the user for permission to change the value (conflict resolution). This differs from the other default values which are suggestions rather than forced values, and it can have unexpected consequences. The thing is, if you have two default values that are in conflict (directly or indirectly) at startup, the model won’t run as the engine isn’t allowed to resolve the conflict on its own. ⚠ Therefore – unless you specifically want to commit a value on beforehand – don’t use the “Default Value” checkbox, use search strategies or soft defaults instead. Simple example model that crashes on startup because of unresolvable Default Value conflict.
The engine will prioritize the defaults mentioned above as follows (first on list happens takes precedence over anything that comes later):
- Default Value (a.k.a. “hard default”)
- Soft function (a.k.a. “soft default”)
- Search strategy
- Component order (Domain order)
Within each method, the prioritization looks like this:
If you are using the default search strategy (ffc_all_vars, which you use if you haven’t explicitly set any search strategy) the engine will start looking at the attributes with the smallest domains and most constraints and for each attribute it will try the domain elements (that is the components if the domain is a class) in ascending order as described above. So for the first field the engine looks at, let’s call it A_field, it will select the first component. For the second field it looks at, let’s call it B_field, it will pick the the first component available unless it is in conflict with the already selected component for A_field, then engine will try the second component, then the third and so on until it finds a valid component for B_field. However, if the model is set up so that the engine prefers starting with B_field, then the first available component will be selected there, which will then affect what components are available for A_field (and all the other fields in the model).
Soft Functions (a.k.a. Soft Defaults)
Soft functions will be executed in the order they appear in the model: start looking at the root part, then move down the part tree depth-first. On each part, start with the first soft function in the constraints list and then go down. Any soft function constraint that cannot be fulfilled will be skipped over.
Search Strategy Actions
As mentioned before, search strategy actions are tried in the order they are listed in the search strategy, any
Try value that cannot be assigned (e.g. if the field has been committed to a different value by the user) is skipped, any subactions to that
Try action will also be skipped then. Later values can never overwrite earlier values.
Default Values (a.k.a. Hard Defaults)
Default Value commits aren’t prioritized since they are commits. If they can be set, they will be set. If two Default Values conflict with each other, the model won’t even start.
Component order doesn’t really impact performance. In some cases picking one component over another significantly limits the solution space, and by putting it at the top of the list the engine will find a solution faster – or by moving it down the engine will need more time. But in most practical cases you will not notice any difference in model performance if you order your components in the order you want them to default. Search strategies can be built to increase the performance of the model or, built the wrong way they can also decrease the performance. Most of the time, however, using search strategies to set a number of default values will not impact performance noticeably. Soft functions are behind the scenes the same thing as search strategies, just that a soft function will always be applied before the search strategy actions. Still, if you have a lot of soft functions, step changes (and model startup) can be a bit slower than if you set the corresponding default values with search strategies. Default Value (a.k.a. “hard default”) – each default value that is set will make the model a little slower, just as each commit by a user will make the model a little slower (remember, the “Default Value” checkbox actually works by committing a value). However, this will only be noticeable once you have a lot of them (as I said: they are commits and when was the last time you noticed the model was slowed down by you committing too many fields?). However, step changes may be up to twice as slow when using “Default Value” since the engine will have to run certain calculations twice if you have introduced at least one Default Value.
What to Use When
In small and simple models, the component order may be enough to set the default values you want. However, it’s not very transparent which defaults will be prioritized when they conflict – if you need to control what default values are more important than others, it’s better to create a custom search strategy with
Try actions ordered in priority order. If you need defaults that are not fixed values, for example defaulting a field to the value of another field, use search strategies combined with a help variable as explained above. Soft functions (a.k.a. “soft defaults”) are easy to use in small/simple models and will override both component order and search strategies. However, just as for component order, you cannot control the priority of the defaults in case they conflict with each other (to do that, use search strategies). For large amounts of defaults – use search strategies instead to ensure good performance. Soft functions can also be necessary to set initial values for postcalc fields if they are involved in complex calculations with many dependencies, so that the engine knows where to start. The “Default Value” setting shouldn’t be used to set defaults unless you want the value to be fixed until the user changes it. All the other ways to set defaults will suggest values for the engine to use, but setting “Default Value” commits the value, which means the engine is forced to use it. If you use this for several fields, where the values for the different fields are in conflict with each other, then the model won’t even start.
Addendum – Domain Order
As mentioned in “Compontent order” above, the component order is really just a special case of “domain order”. Like components, the other domains will also be searched in ascending order (unless the search strategy specifies otherwise), i.e. from the first to the last:
In named domains, the domain element with the lowest value assigned to it will be tried first. For Booleans this means “No” will be the default element since it corresponds to the value “0”, whereas “Yes” corresponds to “1”. The boolean named domain and its values. For other named domains it depends on the values you have assigned to the elements. Of course you can change the priority/order of elements by changing their values, but if there is a natural value to use for each element (e.g. the int value of the flange size in a named domain listing flanges) it’s better to stick with those values and use a search strategy or soft functions to set the default values. Otherwise you risk confusing anyone else working with the model (or yourself). A named domain called “size_nd”, with values that suit the elements.
Integer attributes/fields will start at -10,000,000 and go up from there – unless there is some constraint that sets another min value (which is why it’s good to set limits on int attributes/features if you know they only have a certain range, otherwise you make the engine try pointlessly low numbers (or high, if your search strategy searches in descending order)).
For float attributes/fields only the min and the max values will be checked (in that order, unless the search strategy specifies “descending order” of course).
Functions can take any content so there is no way for the engine to try values for them directly, therefore the “domain order” concept doesn’t apply to them.