Composition
Components and instances
Section titled “Components and instances”A component is a reusable set of declarations and equations. An instance
creates an occurrence with explicit named bindings:
component Offset(parameter input: 1, parameter offset: 1 = 1) { variable output: 1; relation value { output - input - offset = 0; }}
model TwoOffsets() { instance first: Offset(input = 2); instance second: Offset(input = 5, offset = 3);}input is required; offset defaults to 1. The first output is 3 and the second
is 8. Each instance has its own output unknown and equation. Equal parameter
values do not merge instances. Missing required parameters and unknown binding
names are errors.
Imports and conserving connections
Section titled “Imports and conserving connections”import Eqiora.Electrical.Basic.basic as electrical;
/// Ideal 12 V divider with an explicit zero-voltage reference./// Ohm and Kirchhoff give 4 mA through both resistors and an 8 V midpoint.model VoltageDivider() { instance source: electrical.IdealVoltageSource(voltage = 12[V]); instance upper: electrical.Resistor(resistance = 1[kOhm]); instance lower: electrical.Resistor(resistance = 2[kOhm]); instance ground: electrical.Ground();
connect source.positive, upper.positive; connect upper.negative, lower.positive; connect lower.negative, source.negative, ground.terminal;
observable current: A = upper.positive.current; observable midpoint: V = lower.positive.voltage; observable upper_power: W = (upper.positive.voltage - upper.negative.voltage) * upper.positive.current; observable lower_power: W = (lower.positive.voltage - lower.negative.voltage) * lower.positive.current; observable source_power: W = (source.positive.voltage - source.negative.voltage) * source.positive.current;}import Eqiora.Electrical.Basic.basic as electrical makes the module’s public
declarations available through the local name electrical. The project records
the package dependency separately; see adding a package.
connect a, b joins compatible conserving ports. Across values such as voltage
agree, and signed through values such as current into each component sum to zero.
Thus the divider shares one current around its series loop while the two resistors
have different voltage drops.
Read members using the complete path, for example upper.positive.current.
Two ports are compatible when their connector declarations match; matching member
names or vector sizes are not enough. The electrical walkthrough
compiles and runs this complete circuit.
Causal signals
Section titled “Causal signals”Use connect output -> input for a directed signal connection. For example, the
property-composition project sends a sampled temperature
to two consumers:
connect temperature -> local_flux.temperature;connect temperature -> slab.temperature;The signal types and clock identities must agree. This wiring carries a value; it does not apply the flow-conservation rule of a physical connector.
Binding spatial fields and complete boundaries
Section titled “Binding spatial fields and complete boundaries”A component signature can require a support and an existing field:
component UniformTemperature( support body: volume(ambient_dimension = 2), variable temperature: K on body, parameter value: K) { relation uniform on body { temperature = value; }}
model Square() { domain body = box(0, 1, 0, 1); variable temperature: K on body; instance prescribed: UniformTemperature( body = body, temperature = temperature, value = 300[K] );}The component constrains the caller’s temperature field; it does not create a second copy. The same technique lets a volume balance and boundary interface share one displacement or velocity field.
For a component requiring complete_exterior(parent = body), bind
exterior = boundaries(left, right, bottom, top) using every exterior member.
A family member is addressed as surface.mechanical[boundary = left].
See complete solid and fluid models.
Material properties
Section titled “Material properties”A property contract specifies the inputs, output dimension, and derivative requirements of a constitutive value. A property release supplies that value using an analytic expression or a table, together with its validity and attribution.
/// Callable conductivity with derivatives only inside smooth open table segments.public property contract Conductivity(input temperature: K): W / (m * K) { derivatives first_open_intervals;}
/// Synthetic instructional samples; exact data and attribution travel with the package.public property release Samples: Conductivity { table { data conductivity_samples; axis temperature: K; value conductivity: W / (m * K); interpolation piecewise_affine; preprocessing identity; missing reject; knot_derivative reject; endpoint_derivative reject; } validity temperature in [300[K], 360[K]]; outside reject; branch single; citation synthetic_definition; license repository_license;}The property above accepts temperature in kelvin and returns conductivity in W/(m·K). Its table uses piecewise affine interpolation over 300–360 K and rejects values outside that interval. Derivatives are defined inside open segments; knots and endpoints are excluded from derivative evaluation.
A component requests the contract as property conductivity: Conductivity, then
calls it with conductivity(temperature = temperature). The caller binds the
release with conductivity = Samples:
/// Evaluate signed one-dimensional Fourier flux at each supplied sample.public component FourierFlux( clock tick: periodic, property conductivity: Conductivity, input temperature: K at tick, parameter gradient: K / m, output flux: W / m^2 at tick) { relation constitutive at tick { flux = -conductivity(temperature = temperature) * gradient; }}The complete project contains the table data, attribution, package manifest, and two consumers of the same property. Compile the example from the full project, because the property definition needs those files.
For the physical reasoning, read constitutive laws. To publish your own components, follow Create and share a library. For ready-made components, browse the standard library.