Skip to content

Uncertain Starting Vortex

Pipeline description

This example loads an uncertain 2D wing simulation (obtained from an ensemble simulation). This input data contains the upper and lower bounds for the simulation results as two separate scalar fields.

Using both fields, the MandatoryCriticalPoints, representing areas that are guaranteed to locate a critical point of the selected type in any possible realization, are computed (both left views show them as areas in blue for minima and green for maxima).

A realization of the simulation is created by using a normalized random scalar field, interpolating between the lower and upper bound using the random scalar at each point.

As this process introduces noise, a PersistenceDiagram is created (both right views).

From it, first all point pairs are extracted, then retrieving a persistence threshold that is used as a constraint for the TopologicalSimplification to filter the introduced noise.

At last, the ScalarFieldCriticalPoints (top left view, above screenshot) are computed for the smoothed realization (both left views show them as spheres). The critial points extracted from this random realization are indeed located within the regions predicted by the MandatoryCriticalPoints.

ParaView

To reproduce the above screenshot, go to your ttk-data directory and enter the following command:

paraview states/uncertainStartingVortex.pvsm

Python code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/usr/bin/env python

from paraview.simple import *

# create a new 'XML Image Data Reader'
uncertainStartingVortexvti = XMLImageDataReader(
    FileName=["uncertainStartingVortex.vti"]
)

# create a new 'TTK MandatoryCriticalPoints'
tTKMandatoryCriticalPoints1 = TTKMandatoryCriticalPoints(
    Input=uncertainStartingVortexvti
)
tTKMandatoryCriticalPoints1.LowerBoundField = ["POINTS", "lowerBoundField"]
tTKMandatoryCriticalPoints1.UpperBoundField = ["POINTS", "upperBoundField"]
tTKMandatoryCriticalPoints1.NormalizedThreshold = 0.02

# create a new 'Threshold' for the Minimas
threshold6 = Threshold(Input=tTKMandatoryCriticalPoints1)
threshold6.Scalars = ["POINTS", "MinimumComponents"]
threshold6.ThresholdMethod = "Between"
threshold6.LowerThreshold = 0.0
threshold6.UpperThreshold = 2.0

# create a new 'Threshold' for the maximas
threshold5 = Threshold(Input=OutputPort(tTKMandatoryCriticalPoints1, 3))
threshold5.Scalars = ["POINTS", "MaximumComponents"]
threshold5.ThresholdMethod = "Between"
threshold5.LowerThreshold = 0.0
threshold5.UpperThreshold = 8.0

# create a new 'Random Attributes'
randomAttributes1 = RandomAttributes(Input=uncertainStartingVortexvti)
randomAttributes1.DataType = "Double"
randomAttributes1.ComponentRange = [0.0, 0.999]
randomAttributes1.GeneratePointScalars = 1

# create a new 'Calculator'
calculator1 = Calculator(Input=randomAttributes1)
calculator1.ResultArrayName = "realization0"
calculator1.Function = (
    "lowerBoundField+(upperBoundField-lowerBoundField)*RandomPointScalars"
)

# create a new 'TTK PersistenceDiagram'
tTKPersistenceDiagram1 = TTKPersistenceDiagram(Input=calculator1)
tTKPersistenceDiagram1.ScalarField = ["POINTS", "realization0"]

# create a new 'Threshold'
threshold2 = Threshold(Input=tTKPersistenceDiagram1)
threshold2.Scalars = ["CELLS", "PairIdentifier"]
threshold2.ThresholdMethod = "Between"
threshold2.LowerThreshold = 0.0
threshold2.UpperThreshold = 185374.0

# create a new 'Threshold'
persistenceThreshold1 = Threshold(Input=threshold2)
persistenceThreshold1.Scalars = ["CELLS", "Persistence"]
persistenceThreshold1.ThresholdMethod = "Between"
persistenceThreshold1.LowerThreshold = 0.05
persistenceThreshold1.UpperThreshold = 1.75475390406744

# create a new 'TTK TopologicalSimplification'
tTKTopologicalSimplification1 = TTKTopologicalSimplification(
    Domain=calculator1, Constraints=persistenceThreshold1
)
tTKTopologicalSimplification1.ScalarField = ["POINTS", "realization0"]

# create a new 'TTK ScalarFieldCriticalPoints'
tTKScalarFieldCriticalPoints1 = TTKScalarFieldCriticalPoints(
    Input=tTKTopologicalSimplification1
)
tTKScalarFieldCriticalPoints1.ScalarField = ["POINTS", "realization0"]

SaveData("PersistenceDiagram.vtu", tTKPersistenceDiagram1)
SaveData("CriticalPoints.vtp", tTKScalarFieldCriticalPoints1)
SaveData("MandatoryCriticalMinima.csv", OutputPort(tTKMandatoryCriticalPoints1, 0))
SaveData("MandatoryCriticalMaxima.csv", OutputPort(tTKMandatoryCriticalPoints1, 3))

To run the above Python script, go to your ttk-data directory and enter the following command:

pvpython python/uncertainStartingVortex.py

Inputs

Outputs

  • PersistenceDiagram.vtu: the output persistence diagram in VTK file format (bottom right view, above screenshot). You are free to change the vtu file extension to that of any other supported file format (e.g. csv) in the above python script.
  • CriticalPoints.vtp: the output critical points in VTK file format (bottom right view, above screenshot). You are free to change the vtp file extension to that of any other supported file format (e.g. csv) in the above python script.
  • MandatoryCriticalMinima.csv: the output mandatory critical minima points (both left views, blue areas).
  • MandatoryCriticalMaxima.csv: the output mandatory critical maxima points (both left views, green areas).

C++/Python API

MandatoryCriticalPoints

PersistenceDiagram

ScalarFieldCriticalPoints

TopologicalSimplification