FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
VARIABLES section

The <VARIABLES> section defines named variables that can be referenced throughout the input file using $VarName substitution. This is useful for avoiding repetition and making input files easier to maintain.

Warning
Substitution reaches only four places in the file. Writing $Var in an attribute outside that scope is not an error — the literal text $Var is handed to the numeric parser, which reads it as 0. See Where substitution applies before using a variable.

Syntax

<VARIABLES>
<Var Name="WarpLength" Value="35"/>
<Var Name="AnchorPos" Value="10,0,-50"/>
<Var Name="Stiffness" Value="500"/>
</VARIABLES>

Each <Var> element defines a single variable:

Attribute Required Description
Name Yes Variable name. May contain letters, digits, and underscores. Case-sensitive.
Value Yes Replacement value. Can be any string — numbers, vectors, or text.
Note
The element must be spelled <Var> or <var>. Any other child of <VARIABLES> is ignored without warning. If the same Name is defined twice, the first definition wins.

Using variables

Reference a variable by prefixing its name with $ in any attribute value inside the scope described below. The substitution happens at parse time, before SimObjects are created.

<VARIABLES>
<Var Name="Mass" Value="2000"/>
<Var Name="StartPos" Value="10,0,-5"/>
</VARIABLES>
<OBJECTS>
<Lib LibName="fhsim_base" SimObject="Body/Mass" Name="mass"
Mass="$Mass" Scale="0.7"/>
</OBJECTS>
<INITIALIZATION>
<InitialCondition mass.Pos="$StartPos"/>
</INITIALIZATION>

Where substitution applies

Substitution is applied attribute-by-attribute in exactly four places, and nowhere else:

Where What is substituted
<OBJECTS> Every attribute of every child element — including LibName, SimObject and Name, not just the model parameters.
<INTERCONNECTIONS> Every attribute of every <Connection> element (both port references and constants).
<INITIALIZATION> Every attribute of every <InitialCondition> element.
<SIMULATION> The attributes on the <Integrator> element itselfMethod, NumCores, InitialStatesFile, FinalStatesFile.

Everywhere else the $ text survives into the value that the option parser reads. In particular there is no substitution in:

  • <Timing>TStart and TEnd.
  • The <Integrator> child elements: <StepControl>, <LinearSolver>, <Jacobian>, <Diagnostics> and its <Triggers>/<Settings> subtree, and <SundialsExtra>.
  • <Replay>, <Network>, and the simulationSpeed attribute of <SIMULATION>.
  • The whole <OBSERVERS> section.
  • <FromFile> and its <State> children inside <INITIALIZATION>.
Warning
A numeric attribute outside the scope is read with a C atof-style conversion, which yields 0 for text it cannot parse. So <Timing TEnd="$Duration"/> does not fail — it runs a simulation that ends at t = 0. Put the duration in the XML directly, or have the batch script that sets $Duration rewrite TEnd as well.

Rules and behaviour

  • Case-sensitive: $Mass and $mass are different variables.
  • Variable names: May contain letters (a-z, A-Z), digits (0-9), and underscores (_). The name ends at the first character that is not in this set.
  • Multiple variables in one value: You can use multiple $ references in a single attribute value:

    <Var Name="X" Value="10"/>
    <Var Name="Y" Value="20"/>
    <InitialCondition mass.Pos="$X,$Y,0"/>
    <!-- Expands to: mass.Pos="10,20,0" -->
  • Inline mixing: Variables can appear anywhere in a value:

    <Var Name="Suffix" Value="Vis"/>
    <Lib LibName="fhsim_base$Suffix" SimObject="Body/Mass" Name="mass"/>
    <!-- Expands to: LibName="fhsim_baseVis" -->
  • Undefined variables cause an error: If a $Name reference does not match any defined variable, FhSim reports an error and stops.
  • Substituted text is rescanned: the scan resumes at the start of the text it just inserted, so a variable whose Value itself contains $Other is expanded further. This makes variables composable, but a variable that references itself never terminates — do not write <Var Name="A" Value="$A"/>.

Arithmetic in attribute values

After substitution, values in <OBJECTS>, <INTERCONNECTIONS> and <INITIALIZATION> are passed through an arithmetic evaluator. It supports +, -, *, /, ^ and parentheses, so a value can be written as a calculation instead of a pre-computed number:

<VARIABLES>
<Var Name="X" Value="10"/>
<Var Name="Depth" Value="50"/>
</VARIABLES>
<OBJECTS>
<Lib LibName="fhsim_base" SimObject="Body/Mass" Name="mass"
Mass="2*1000"/>
</OBJECTS>
<INITIALIZATION>
<InitialCondition mass.Pos="$X*2,0,-$Depth/2"/>
<!-- Expands to: mass.Pos="20,0,-25" -->
</INITIALIZATION>

This applies to the three sections above only. <Integrator> attributes get variable substitution but no arithmetic, and nothing outside the four places listed above gets either.

When a value is treated as an expression

The evaluator is deliberately conservative, because the same attributes also carry file paths, material names and endpoints. The whole value is left untouched when it

  • is empty, or is a single character; or
  • contains a semicolon (;) — the marker for a path or unit string.

Otherwise the value is split on commas and each field is evaluated on its own. A field is left untouched when it

  • looks like an IP address — more than one . and none of * / ^ + -; or
  • contains any letter other than e/E (an underscore also counts as a letter here), so Simple/Black and tcp://*:5555 survive; or
  • contains no digit, or contains an e/E before its first digit.

Every field that passes those tests is evaluated — including one that is already a plain number.

Warning
The result is written back with six significant digits. A field that gets evaluated therefore loses precision beyond that: Mass="1.23456789" is rewritten as 1.23457, and Ratio="1/3" becomes 0.333333. Scientific notation survives (1e-7 stays 1e-07), so write a value that needs more than six digits in a form the rules above skip, or accept the rounding.
Note
Unary minus is only recognised at the start of a field, after (, and after +/-. 2*-3 is not an expression the evaluator accepts; write 2*(0-3).

Typical use cases

Parameterising a scenario for sweep studies

Define key parameters as variables so they can be easily changed (or overridden by batch scripts that rewrite the <VARIABLES> section):

<VARIABLES>
<Var Name="WarpLength" Value="35"/>
<Var Name="TowSpeed" Value="2.5"/>
</VARIABLES>
<INTERCONNECTIONS>
<Connection
winch.WireLength="$WarpLength"
vessel.Velocity="$TowSpeed,0,0"
/>
</INTERCONNECTIONS>

The simulated duration is not a candidate: <Timing TEnd> is outside the substitution scope.

Sharing positions across objects

<VARIABLES>
<Var Name="MountPoint" Value="5,0,3"/>
</VARIABLES>
<INTERCONNECTIONS>
<Connection
cable.PosA="$MountPoint"
sensor.ReferencePoint="$MountPoint"
/>
</INTERCONNECTIONS>

See also