How to obtain a continuum view of SPH particles in OVITO?

Hi Ovitors

Usually, we visualize the LAMMPS simulation results in the particle (discrete) view. But here I am doing the SPH simulation and I want to have a continuum view of the results. I’ve known that in Paraview, it can be done by the SPH volume interpolation filter. How can it be obtained by OVITO?

Below is an OVITO example from Alessio Alexiadis et al.'s research article (https://doi.org/10.1098/rsif.2020.1024) to help illustrate this question. Thanks in advance.

1 Like

Hi, I see two possible workflows to create this kind of visualization.

  1. You have the option to apply several instances of the Construct Surface Mesh modifier to your particle data and make use of its capability to take into account only a selection (subset) of particles. Construct surface mesh — OVITO User Manual 3.10.4 documentation
  2. You could also use a combination of OVITO’s Spatial binning and Create isosurface modifiers.
    Spatial binning pro — OVITO User Manual 3.10.4 documentation
    Create isosurface — OVITO User Manual 3.10.4 documentation

Hi @kalcher . I tried Spatial Binning to average the velocity as you advised. It doesn’t work for the water collapse case. The averaged velocities are very rough and change steeply.

Here is my python code:

import os
from ovito.io import import_file, export_file
from ovito.modifiers import SpatialBinningModifier as SBM


def bin_3d(fileName, outputName, itemName, counts, frame=-1,
           operation="mean"):
    if operation != "mean":
        tmp_operation = operation.lower()
        operation_dict = {
            "mean": SBM.Operation.Mean,
            "min": SBM.Operation.Min,
            "max": SBM.Operation.Max,
            "sum": SBM.Operation.Sum,
            "sumvol": SBM.Operation.SumVol
        }
        RealOperation = operation_dict.get(tmp_operation, 0)
    else:
        RealOperation = SBM.Operation.Mean
    pipeline = import_file(fileName)
    pipeline.modifiers.append(SBM(
        property=itemName,
        direction=SBM.Direction.XYZ,
        bin_count=counts,
        reduction_operation=RealOperation))
    if frame == -1:
        if not os.path.exists(itemName):
            os.mkdir(itemName)
        outputName = f'{itemName}\\{outputName}'
        for frm in range(pipeline.source.num_frames):
            pipeline.compute(frm)
        export_file(pipeline, outputName, 'vtk/grid',
                    key='binning', multiple_frames=True)
    else:
        pipeline.compute(frame)
        export_file(pipeline, outputName, 'vtk/grid', key='binning')


bin_3d('water.dump', 'velocity*.vtk', 'Velocity', (500, 500, 1), frame=-1, operation='mean')

I change the counts value from (500,500) to (200,200). The graph is much smoother now.

Different smooth operations were tried.

The mean operation underestimated the velocity.

The max operation overestimated the velocity.

The min operation gave a good estimate out of surprise. In principle, it should yield lower values than mean.

The min operation gave a good estimate out of surprise. In principle, it should yield lower values than mean.

This is not as expected. Could you send me the dump file used as input so I can replicate the analysis on my machine?
If you don’t want to share the data publicly you can also send me a DM here on matsci.

@utt Thank you for your interest. I tried to upload the dump file just now but was given “sorry, there was an error uploading that file”. Maybe I can alternatively email you the file if you are willing to provide the email address.

Sure, please send the file to [email protected]

The email has been sent :slight_smile:

Thanks, I checked you file in OVITO and here the binning seems to work as intended. Using max as the operation give a value range from 0 to 6.46, using min gives a range from 0 to 6.38, and using mean results in values from 0 to 6.43. See the attached screenshot for reference.



For reference, I used the last snapshot of the trajectory in your dump file with an x-y binning directions and a bin size of 40 by 80.

I see that you visualize the results outside OVITO (in paraview?) so there might be an issue with data transfer or post-processing.

1 Like

Looks cool! Since I have no OVITO pro, I use the OVITO Python module to process data and use Paraview to visualize. Could you please provide the post-processing code for me (I mean for visualization because I am new to OVITO) to check quickly what is wrong?

These are the modifier settings I used:

# Boilerplate code generated by OVITO Pro 3.10.3
from ovito.io import *
from ovito.modifiers import *
from ovito.data import *
from ovito.pipeline import *

# Data import:
pipeline = import_file('water.dump', multiple_frames = True)

# Spatial binning:
pipeline.modifiers.append(SpatialBinningModifier(
    property = 'Velocity Magnitude', 
    reduction_operation = SpatialBinningModifier.Operation.Mean, 
    direction = SpatialBinningModifier.Direction.XY, 
    bin_count = (80, 160, 1)))

Thank you utt. You provided SpatialBinningModifier code. What I wonder is how to visualize it in python. I guess it may need ColorCodingModifier? So I added it but only obtained a figure without binning.

This is my clumsy code :frowning:

from ovito.modifiers import SpatialBinningModifier, ColorCodingModifier
import math
from ovito.vis import Viewport
from ovito.vis import TachyonRenderer
from ovito.io import import_file, export_file

# Data import:
pipeline = import_file('water.dump', multiple_frames=True)

# Spatial binning:
pipeline.modifiers.append(SpatialBinningModifier(
    property='Velocity Magnitude',
    reduction_operation=SpatialBinningModifier.Operation.Mean,
    direction=SpatialBinningModifier.Direction.XY,
    bin_count=(80, 160, 1)))
pipeline.modifiers.append(ColorCodingModifier(
    property='Velocity Magnitude',
    gradient=ColorCodingModifier.Jet()
))
vis_element = pipeline.compute().particles.vis
vis_element.radius = 1e-2

pipeline.add_to_scene()
vp = Viewport()
vp.type = Viewport.Type.Perspective
vp.camera_pos = (2, 4, 14)
vp.camera_dir = (0, 0, -1)
vp.fov = math.radians(35)
tachyon = TachyonRenderer(shadows=False, direct_light_intensity=1.1, ambient_occlusion=False)
vp.render_image(filename="figure.png", background=(1, 1, 1), renderer=tachyon, frame=200)

Finally, I realize where I went wrong. I specified the property as “Velocity” in SpatialBinningModifier originally and obtained underestimated velocity. Now I change “Velocity” to “Velocity Magnitude”, and the values look good in Paraview now.

The reason why I selected the property as “Velocity” was that the velocity in Paraview had X, Y, Z components and the magnitude. It is a vector and enables me to draw the arrow plot in Paraview.
image
Unfortunately, the values are wrongly estimated.

1 Like