Components
Components are the main unit of Dyad. A Dyad "model" is components all the way down, which can use or extend each other.
Components can contain other components, variables, parameters, and relations. They can also extend other components or partial components for code reuse.
Inheritance
Any component can extend, or inherit from, any other component. This means that the new component will have all the variables, parameters, and relations of the base component, plus any additional variables, parameters, and relations defined in itself.
The way this is done is by using the extends keyword in the component definition. Let's say we have a base component FirstOrder, which is a simple linear system:
component FirstOrder
variable x::Real
variable k::Real
relations
initial x = 1
initial k = 1
der(x) = k
endNow, we can define a new component SecondOrder that extends FirstOrder, adds a new parameter z, and uses it to drive the k parameter of FirstOrder:
component SecondOrder
extends FirstOrder
parameter z::Real = 1
relations
der(k) = z
endPartial components
Partial components are components that are not complete on their own, but can be used as a base for other components.
You can define a partial component by prefixing the component definition with partial.
partial component MyPartialComponent
variable x::Real
parameter y::Real
relations
# ...
endThen, regular components (or other partial components) can extend it:
component MyComponent
extends MyPartialComponent
parameter z::Real
relations
initial x = 0
der(x) = y + z
endHere, MyComponent has all the variables and parameters of MyPartialComponent, even though we haven't explicitly written them out in the definition.
Partial components and inheritance are very useful for sharing code between components, without requiring components that share a common structure but differ in their specific parameters and behaviour, like electric circuit parts. See the RLC Circuit tutorial for an example of using inheritance from partial components.
The advantage of inheritance over simply using a sub-component is namespacing: the all the variables and parameters of the base component are available directly in the new component, without having to prefix them with the base component's name.
For example, if we have a base component MyBaseComponent with a variable x, and a component MyComponent that extends it, then we can refer to x simply as mycomponent.x. If MyComponent did not extend MyBaseComponent, but instead had a subcomponent base = MyBaseComponent(), then we would have to refer to x as mycomponent.base.x - significantly more inconvenient! :::