FlowTrajectory#

class FlowTrajectory(velocity_field, map_dimensions, additional_dimension_mapping=None, **kwargs)[source]#

Numerically integrates the path of particles in a velocity field and simultaneoulsy looks up all additional field values for the previous particle positions.

Example usage
Instantiation#
velocity_field_3d = ...  # shape - (X, Y, Z, 3)
map_dimensions = [(x_lo, x_hi), (y_lo, y_hi), (z_lo, z_hi)]
field_list = []  # ... no addition a field mapping
trajectory_module = FlowTrajectory(velocity_field_3d, map_dimensions, field_list)
Call function#
r_init = ...  # initial_positions of shape (N, 3)
timing = np.arange(0., 1.01, 0.01)
r_at_timing, fields = trajectory_module(r_init, timing, dt_max=0.01,
                                       return_velocities=True)
increment particle positions#
r_init = ...  # initial_positions of shape (N, 3)
delta_t = tf.constant(0.01, tf.float32)
r_new, fields = self.trajectory_module.increment_particles(r_init, dt=delta_t)
Parameters:
  • velocity_field (ndarray) – (X, Y, Z, 3+n) 3D map storing gridded velocities in m/s at positions X, Y, Z. Unit should be m/ms Additional dimensions past 3 are treated as additional data fields

  • map_dimensions (ndarray) – (3, 2) -> [(xlow, xhigh), (ylow, yhigh), (zlow, zhigh)] Physical extend of the gridded velocity fields.

  • additional_dimension_mapping (List[Tuple[str, int]]) – List of name/len pairs to unstack the looked up values. If not None this mapping must explain all ‘n’ additional dimension in the parameter velocity-field e.g. [(‘off_res’, 1)] meaning that off-resonance for all time points has a size of 1, starting from index 3 in velocity field.

  • kwargs

    • device: str defaults to CPU:0

Methods:

__call__(initial_positions, timing, dt_max)

Evaluates the increment particle function for multiple steps, and for the times matching the argument values, stores the position.

increment_particles(particle_positions, dt)

For given particle positions and specified time-interval returns the values of all additional fields at the initial particle position and moves the particles according to:

__call__(initial_positions, timing, dt_max, verbose=True, return_velocities=False)[source]#

Evaluates the increment particle function for multiple steps, and for the times matching the argument values, stores the position.

Parameters:
  • initial_positions (Tensor) – (#particles, 3)

  • timing (Tensor) – float - in seconds

  • dt_max (float) – Maximal temporal step width in milliseconds

  • verbose (bool) – bool

  • return_velocities (bool) – if True, the velocities for each time-step is saved and returned as entry of the additional fields dictionary

Return type:

(Tensor, dict)

Returns:

(#particles, n_steps, 3) - tf.Tensors, Trajectory, dict(field-name: tf.Tensor with shape (#particles, n_steps, n_components)) field values at trajectory locations

increment_particles(particle_positions: ~tensorflow.python.framework.ops.Tensor, dt: ~tensorflow.python.framework.ops.Tensor, return_velocities: bool = False) -> (<class 'tensorflow.python.framework.ops.Tensor'>, <class 'dict'>)[source]#

For given particle positions and specified time-interval returns the values of all additional fields at the initial particle position and moves the particles according to:

\[r_{t+1} = r_{t} + \delta t v(r_{t})\]

where v is assumed to be specified in m/ms and \(\delta t\) in ms

Parameters:
  • particle_positions (Tensor) – (-1, 3) batch of 3D particle coordinates

  • dt (Tensor) – scalar value in ms

  • return_velocities (bool) – if True the additional field lookup contains the field “velocity”

Return type:

(Tensor, dict)

Returns:

new particle positions (-1, 3), dict(**additional_fields[-1, c])