Using sensors

In this section we describe how to create and use virtual sensors in Lizzy. All operations can be performed using the LizzyModel user-facing methods.

Sensors in Lizzy

In Lizzy, a virtual sensor is represented by the Sensor class. A sensor is a point probe placed at a specific location in the domain. During the simulation, Lizzy records the local values of pressure, velocity, and fill factor at the sensor location at each time step, making them available for reading at runtime or post-processing.

Creating sensors

Note

The following operations are to be performed before the solver is initialised by calling initialise_solver().

To create a sensor, use the create_sensor() method, providing an name for the sensor and the (x, y, z) coordinates of the position where it will be placed. For example, to place a sensor called “sensor_01” at position (0.5, 0.5, 0.0):

model.create_sensor("sensor_01", (0.5, 0.5, 0.0))

You can create as many sensors as needed.

Fetching sensors from the model

To retrieve a sensor object from the model, use the get_sensor_by_name() method, providing the sensor’s name:

sensor = model.get_sensor_by_name("sensor_01")

This returns the Sensor object with that name.

Note

This method can be called both before and after the solver has been initialised.

Reading sensor data at runtime

Sensor data is only available after the solver has been initialised by calling initialise_solver(). The solver stores filed values at created sensors at the end of each write-out time period (specified in the simulation parameters). The following read-only properties are available in a Sensor object:

  • name: the name of the sensor.

  • position: the (x, y, z) coordinates of the sensor.

  • pressure: the current resin pressure (Pa) at the sensor location.

  • velocity: the current resin velocity (m/s) at the sensor location.

  • fill_factor: the current fill factor at the sensor location (0 = empty, 1 = fully filled).

  • time: the current simulation time (s).

  • resin_arrived: boolean that is True if the resin front has reached the sensor location.

  • trigger_time: the time at which the sensor was triggered by the resin arrival.

For example, after advancing the simulation, we can read the sensor values as follows:

model.solve_time_interval(300)
sensor = model.get_sensor_by_name("sensor_01")
print(sensor.time)
print(sensor.pressure)
print(sensor.fill_factor)
>>> 300.0
>>> 87432.5
>>> 0.73

To print a summary of all sensor readings at a given instant, use the print_sensor_readings() method:

model.print_sensor_readings()
>>> {0: 'time: 300.0 s; resin pressure: 87432.5 Pa; fill factor: 1.0, resin velocity: [0.00012 0. 0.] m/s, resin arrived: True, trigger time: 160.0 s',
     1: 'time: 300.0 s; resin pressure: 54210.1 Pa; fill factor: 1.0, resin velocity: [0.00009 0. 0.] m/s, resin arrived: True, trigger time: 250.0 s'}

Resin arrival detection

Each sensor has a resin_arrived boolean attribute that becomes True as soon as the fill factor at the sensor location reaches or exceeds 0.5, and a trigger_time attribute that records the time at which the arrival happened. For example:

sensor = model.get_sensor_by_name("sensor_01")
if sensor.resin_arrived:
    print(f"Resin has reached this sensor at time= {sensor.trigger_time} s")

To get the trigger state of all sensors at once as a list of booleans, use the get_sensor_trigger_states() method:

states = model.get_sensor_trigger_states()
print(states)
>>> [True, True, False]

In this example, the first 2 sensors have been reached by resin, the third one hasn’t.

Triggering write-outs on sensor events

By enabling the end_step_when_sensor_triggered simulation parameter, Lizzy will automatically end the current solution step and create a result write-out whenever a sensor transitions to the triggered state (i.e., when the resin front reaches a sensor for the first time). This ensures that the exact moment of resin arrival is always captured in the solution, independently of the regular write-out schedule (output_interval).

To enable this behaviour, set the parameter before initialising the solver:

model.set_simulation_parameters(end_step_when_sensor_triggered=True)

See Simulation Parameters for more details on simulation parameters.

Building dynamic scenarios with sensors

Sensors become useful when combined with the solve_time_interval() method to create dynamic filling scenarios. For example, we can advance the simulation in short intervals, check the sensor state after each interval, and react accordingly:

Tip

The following example shows how to close an inlet as soon as the resin reaches a sensor, simulating a sequential infusion strategy:

model.set_simulation_parameters(end_step_when_sensor_triggered=True)
model.initialise_solver()

# Fill until resin reaches sensor 01 (located at the mid-point of the part)
while not model.get_sensor_by_name("sensor_01").resin_arrived:
    model.solve_time_interval(10)

# Resin has arrived at sensor 01: close inlet_1 and open inlet_2
model.close_inlet("inlet_1")
model.open_inlet("inlet_2")

# Continue filling until the part is completely filled
model.solve()

See also

Boundary conditions operations

Opening, closing and modifying inlets at runtime.

Sensor API reference

Full list of properties and methods available on the Sensor class.