Lagrangian Analysis

Overview

Lagrangian analysis is an in situ data reduction operator used for time-dependent vector field data generated by a simulation code. With the objective of storing/representing fluid dynamics data in its Lagrangian representation, the Lagrangian analysis functionality is implemented as a VTK-m filter. The filter operates by placing seeds and calculating the corresponding particle trajectories in the flow volume. These particle trajectories encode the underlying behavior of the flow field. Calculating and extracting a Lagrangian representation of a flow field offers significantly improved accuracy-storage propositions for time-dependent flow visualization compared to the traditional (Eulerian) method. Thus, the Lagrangian analysis filter enables data reduction of large vector fields while maintaining high data integrity.

Lagrangian analysis operates as a two-phase approach. The first phase is performed in situ and involves calculating and extracting flow field information. The second phase is performed post hoc and involves interpolating the extracted information to perform time-dependent flow visualization.

To calculate a Lagrangian representation in situ, we uniformly seed particles in the volume and advect the particles for nonoverlapping pre-determined intervals of time. The calculated particle trajectories are referred to as basis flows. The extracted basis flows are accurate given they use the complete spatial and temporal resolution of the simulation vector field during advection in situ. For each basis flow, the start location and end location of the particle trajectory is known.

The stored basis flow information can be interpolated post hoc to perform exploratory time-dependent flow visualization. Complete pathlines can be calculated by concatenating results from batches of basis flows.

Getting Started

Lagrangian analysis functionality is accessible via Ascent. In situ extraction of time-dependent vector field data is implemented using VTK-m, VTK-h filters and a VTK-m particle advection worklet. The Ascent library is light-weight infrastructure that is directly integrated with the simulation code. Depending on the particular use case (for example, operating on a single node), Lagrangian analysis can also be directly performed using the VTK-m filter.

To perform in situ extraction, several parameters can be specified to the Lagrangian analysis filter. These include:

  1. Vector field name (“field”) - the name of the vector field whose Lagrangian representation is to be calculated
  2. Step size (“step_size”)- the unit of time a particle advances between each cycle
  3. Write frequency (“write_frequency”) - the number of cycles between writing basis flow information to disk, i.e., the interval length
  4. Custom seeding resolution (“cust_res”) - 0 or 1. The default value 0 results in a 1:1 seed resolution, i.e., number of seeds to grid points. The value of 1 allows the user to specify a custom seed resolution. This is achieved by specifying the number of seeds to grid points along each axis:
    • Reduction factor in X direction (“x_res”)
    • Reduction factor in Y direction (“y_res”)
    • Reduction factor in Z direction (“z_res”)

These parameters can be specified by manually setting the values using filter object functions or by passing values via an ascent_actions.json file.

Use Case Examples

To demonstrate the use of Lagrangian analysis, we use the Cloverleaf3D proxy application that is available as an example integration with the Ascent library.

Below is an example ascent_actions.json file that can be used to extract time-dependent vector fields in a Lagrangian representation from the Cloverleaf3D. The pipeline of operations to be performed contains the name of the filter - “lagrangian”, followed by the specific parameters required to configure the filter. For the Cloverleaf3D proxy application, a vector field named “velocity” is generated. For other simulation codes, the respective vector field name will need to be used. We can specify the step size used for advection (in this example we use “0.02”). If cust_res is set to 0, then the number of particles used is the same as the number of grid points, i.e., a 1:1 configuration. In our example, we set cust_res to 1, indicating we do not want to use the default seed resolution. We set x_res, y_res and z_res to 2, i.e., a particle is placed for every other grid point in each axis direction. Thus, for this custom seed resolution we are using 1:8 particles to grid points.

[
  {
    "action": "add_pipelines",
    "pipelines":
    {
      "pl1":
      {
        "f1":
        {
          "type": "lagrangian",
          "params":
          {
            "field": "velocity",
            "step_size": 0.02,
            "write_frequency": 25,
            "cust_res": 1,
            "x_res": 2,
            "y_res": 2,
            "z_res": 2
          }
        }
      }
    }
  },
  {
    "action": "execute"
  },
  {
    "action": "reset"
  }
]

Additionally, in the event the user does not want to use an ascent_actions.json file, the code can be directly instrumented. The C++ code snippet below demonstrates the same Lagrangian analysis filter configuration as the instance above. Further, this example utilizes Ascent relay extract functionality to store the calculated basis flow data.

Ascent ascent;
Node ascent_opts;
ascent_opts["runtime/type"] = "ascent";
ascent.open(ascent_opts);
conduit::Node mesh_data;
// Populate mesh_data;

conduit::Node extracts;
extracts["e1/type"]  = "relay";
extracts["e1/pipeline"]  = "pl1";
extracts["e1/params/path"] = output_file_path;

conduit::Node pipelines;
// pipeline 1
pipelines["pl1/f1/type"] = "lagrangian";
// filter knobs
conduit::Node &lagrangian_params = pipelines["pl1/f1/params"];
lagrangian_params["field"] = "velocity";
lagrangian_params["step_size"] = 0.02;
lagrangian_params["write_frequency"] = 25;
lagrangian_params["cust_res"] = 1;
lagrangian_params["x_res"] = 2;
lagrangian_params["y_res"] = 2;
lagrangian_params["z_res"] = 2;
conduit::Node actions;
// add the pipeline
conduit::Node &add_pipelines = actions.append();
add_pipelines["action"] = "add_pipelines";
add_pipelines["pipelines"] = pipelines;
// add the extracts
conduit::Node &add_extracts = actions.append();
add_extracts["action"] = "add_extracts";
add_extracts["extracts"] = extracts;
// execute
conduit::Node &execute  = actions.append();
execute["action"] = "execute";
// reset
conduit::Node &reset  = actions.append();
reset["action"] = "reset";
ascent.publish(mesh_data);
ascent.execute(actions);
ascent.close();

Parameter Value Selection

In the use cases above, we have selected parameters that are appropriate to extract time-dependent vector field information from the Cloverleaf3D proxy application.

  1. “field”: We choose the vector field “velocity” that is generated by the Cloverleaf3D application.
  2. “step_size”: The example step size we use is equal to the duration that the simulation advances every cycle, i.e., one cycle corresponds to the simulation advancing by 0.02 units of time.
  3. “write_frequency”: Depending on how often the user wants to save data, an appropriate value for write frequency should be selected. Lagrangian basis flows represent an interval of time. In the example above, we select a value of 25. For the Cloverleaf3D application this would be considered a short/medium interval length. If the simulation executes for approximately 200 cycles - then 8 sets of basis flows, each representing an interval of 25 cycles, would be stored.
  4. “cust_res”: Custom resolution needs to be enabled (value = 1) in order to achieve a data reduction. By default, the Lagrangian filter will use a 1:1 configuration, i.e., it will use as many particles as grid points.
  5. “x_res”, “y_res”, “z_res”: These parameters control the degree on data reduction. We recommend using either values of 2, i.e., every other grid point in each direction or 1:8 data reduction, or 3, i.e., every third grid point in each direction or 1:27 data reduction. Setting each parameter to 4 would result in a 1:64 data reduction and could reduce data integrity.

Performance

To improve overall performance of the Lagrangian analysis the filter particle advection worklet is capable of utilizing hardware accelerators for improved performance. Further, we adopt a communication-free model and eliminate integration of basis flow trajectories across node boundaries to improve scalability.

Post Hoc Reconstruction

To utilize the extracted Lagrangian representation, a reconstruction filter is available in VTK-h and accessible through Ascent.

Required Input Format Information: The VTK-h filter currently accepts “.vtk” structured grid files with a “displacement” vector field and “valid” scalar field defined at each grid point. Further, the current setup requires the files follow a particular naming format in order to support loading data generated across multiple ranks and time-stamps. Files should be named “Lagrangian_Structured_RANK_INTERVAL.vtk”, where RANK specified the rank that generated the file and INTERVAL specified the interval the file encoded. For example, for particle trajectories calculated starting at cycle 0 and stored at cycle 10, and generated by rank 5, the file would be named Lagrangian_Structured_5_10.vtk. For the next interval, i.e., 10 to 20, the file would be named Lagrangian_Structured_5_20.vtk.

The second required information is a file containing seed locations. Currently, this information is read in from a text file following the format “X1 Y1 Z1” on each line, where each line specifies the location of one seed particle.

  conduit::Node pipelines;
// pipeline 1
pipelines["pl1/f1/type"] = "lagrangian_interpolation";
// filter knobs
conduit::Node &lagrangian_params = pipelines["pl1/f1/params"];
lagrangian_params["field"] = "braid";
lagrangian_params["radius"] = 0.1;
lagrangian_params["num_seeds"] = 1000;
lagrangian_params["interval"] = 10;
lagrangian_params["start_cycle"] = 10;
lagrangian_params["end_cycle"] = 100;
lagrangian_params["seed_path"] = "path/to/seed/file/Seed.txt";
lagrangian_params["basis_path"] = "path/to/extracted/data/";
lagrangian_params["output_path"] = "path/to/output/data/Pathlines_"; // Name of output file begins with "Pathlines_"

conduit::Node actions;
// add the pipeline
conduit::Node &add_pipelines = actions.append();
add_pipelines["action"] = "add_pipelines";
add_pipelines["pipelines"] = pipelines;
//
// Run Ascent
//
Ascent ascent;
Node ascent_opts;
ascent_opts["runtime/type"] = "ascent";
ascent_opts["mpi_comm"] = MPI_Comm_c2f(comm);
ascent.open(ascent_opts);

// create dummy mesh using conduit blueprint
Node n_mesh;
conduit::blueprint::mesh::examples::braid("hexs",
                                            2,
                                            2,
                                            2,
                                            n_mesh);
  // publish mesh to ascent
ascent.publish(n_mesh);
actions.append()["action"] = "execute";
Node &reset  = actions.append();
reset["action"] = "reset";
// execute
ascent.execute(actions);
ascent.close();

Parameter Information The post hoc reconstruction routine accepts multiple parameters. We provide information for each of these below.

  1. “radius”: Each grid point with a valid = 0 is reconstructed using a scattered point interpolation. The radius determines which neighboring points to use for reconstruction.
  2. “num_seeds”: Specifies the number of seed particles to be reconstructed and specified in the seed file.
  3. “interval”: Temporal subsampling rate at which files were stored to disk.
  4. “start_cycle”: This parameter specifies the first interval that should be loaded from disk and used for reconstruction. Will typically be equal to interval, unless user wants to reconstruct pathlines starting at a different time in the simulation.
  5. “end_cycle”: This parameter specifies the last interval that should be reconstructed.
  6. “seed_path”: Path to the seed file.
  7. “basis_path”: Path to the extracted Lagrangian data.
  8. “output_path”: Specified the path to store calculated particle trajectories as well as allows specifying the output file name.

Developers

Sudhanshu Sane