Tutorial 3: How to select the best settings and advanced options
Outline
Avoid large size differences between neighboring cells
Controlling the uniformity of the grid
Accelerating the refinement process for large 3D datasets
In this tutorial, we will learn about how to avoid large size differences between neighboring cells as encountered in the previous tutorial. Then we will look at some important parameters, which can be customized to control the topology of the grid. We will lastly see how we can use these parameters for large grids in combination with STL files for geometry objects.
In this tutorial we will again use the cylinder2D from the first tutorial since it is easy and fast to execute and publicly available for everybody.
1. Avoid large size differences between neighboring cells
For some applications, e.g., when computing gradients or in case a good resolution of the geometry has to be ensured, large size differences between two neighboring cells may cause problems. We need to ensure smooth transitions within cell sizes across the grid in these cases. \(S^3\) provides an additional argument, which can be set to ensure a max. level difference between two neighboring cells of one. The cell level refers here to the number of refinement we have to employ to get to this specific cell size.
To activate this criterion, we have to set max_delta_level=True when instantiating the s_cube object. This constraint will lead to smooth transitions, but also to longer execution times and mesh sizes, so it is recommended to only activate it when necessary.
[1]:
import sys
import torch as pt
from os import environ
from os.path import join
environ["sparseSpatialSampling"] = join("..", "..", "..")
sys.path.insert(0, environ["sparseSpatialSampling"])
from sparseSpatialSampling.export import ExportData
from sparseSpatialSampling.sparse_spatial_sampling import SparseSpatialSampling
from sparseSpatialSampling.geometry import CubeGeometry, SphereGeometry
from sparseSpatialSampling.utils import load_foam_data
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
[2]:
# define load paths to the CFD data, assuming they are in the top-level of the repository
load_path = join("..", "..", "..", "flowTorch_Workshop_2025", "cylinder_2D_Re100")
# define the path to where we want to save the results and the name of the file
save_path = join("..", "..", "..", "run", "tutorials", "tutorial_3")
# define boundaries of the masked domain for the cylinder, here we want to load the full domain
bounds = [[0, 0], [2.2, 0.41]] # [[xmin, ymin], [xmax, ymax]]
# load the CFD data, we want to compute the metric based on the velocity in the quasi-steady state, so omit the first 8 seconds
field, coord, _, write_times = load_foam_data(load_path, bounds, field_name="U", t_start=8, scalar=False)
[2026-02-19 15:38:32] INFO Loading precomputed cell centers and volumes from processor0/constant
[2026-02-19 15:38:32] INFO Loading precomputed cell centers and volumes from processor1/constant
[3]:
# now we compute a metric. in this case, we just use the temporal mean of the abs. velocity vector
metric = pt.mean(field.abs().sum(1), 1)
# create geometry objects for the domain and the cylinder
# we don't want to refine the domain boundaries, so keep all the optional arguments as default
domain = CubeGeometry("domain", True, bounds[0], bounds[1])
# we explicitly increase the resolution of the cylinder to cause large level differences when the constraint is not activated
geometry = SphereGeometry("cylinder", False, [0.2, 0.2], 0.05, refine=True, min_refinement_level=12)
[4]:
# now we artificially create poor grid containing large level differences
s_cube = SparseSpatialSampling(coord, metric, [domain, geometry], save_path, "cylinder2D_nodeltaLevel_constraint", "cylinder2D",
min_metric=0.5, n_jobs=4)
s_cube.execute_grid_generation()
# export only the last time step for demonstration purposes
export = ExportData(s_cube, write_times="10")
export.export(coord, field[:, :, -1].unsqueeze(-1), "U")
[2026-02-19 15:38:33] INFO Selecting min. approximation of the metric as stopping criterion.
[2026-02-19 15:38:33] INFO
Selected settings:
pre_select : False
n_jobs : 4
max_delta_level : False
geometry : ['domain', 'cylinder']
min_metric : 0.5
min_level : 5
cells_per_iter_start : 9
cells_per_iter_end : 9
cells_per_iter : 9
cells_per_iter_last : 1000000000.0
reach_at_least : 0.75
n_dimensions : 2
n_cells_orig : 9800
relTol : 0.001
[2026-02-19 15:38:33] INFO Starting grid generation.
[2026-02-19 15:38:33] INFO Starting uniform refinement.
Starting iteration no. 0, N_cells = 1
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Starting iteration no. 1, N_cells = 4
Starting iteration no. 2, N_cells = 8
Starting iteration no. 3, N_cells = 16
Starting iteration no. 4, N_cells = 64
[2026-02-19 15:38:38] INFO Finished uniform refinement.
[2026-02-19 15:38:38] INFO Starting metric-based refinement.
Starting iteration no. 0, captured metric: 13.64 %, N_cells = 192
Starting iteration no. 1, captured metric: 14.5 %, N_cells = 217
Starting iteration no. 2, captured metric: 15.03 %, N_cells = 244
Starting iteration no. 3, captured metric: 15.55 %, N_cells = 271
Starting iteration no. 4, captured metric: 16.13 %, N_cells = 298
Starting iteration no. 5, captured metric: 16.37 %, N_cells = 325
Starting iteration no. 6, captured metric: 16.52 %, N_cells = 352
Starting iteration no. 7, captured metric: 16.65 %, N_cells = 379
Starting iteration no. 8, captured metric: 16.9 %, N_cells = 406
Starting iteration no. 9, captured metric: 17.45 %, N_cells = 433
Starting iteration no. 10, captured metric: 18.37 %, N_cells = 459
Starting iteration no. 11, captured metric: 18.99 %, N_cells = 486
Starting iteration no. 12, captured metric: 19.58 %, N_cells = 513
Starting iteration no. 13, captured metric: 20.31 %, N_cells = 540
Starting iteration no. 14, captured metric: 21.01 %, N_cells = 567
Starting iteration no. 15, captured metric: 21.71 %, N_cells = 594
Starting iteration no. 16, captured metric: 22.66 %, N_cells = 621
Starting iteration no. 17, captured metric: 23.54 %, N_cells = 648
Starting iteration no. 18, captured metric: 24.35 %, N_cells = 674
Starting iteration no. 19, captured metric: 25.03 %, N_cells = 701
Starting iteration no. 20, captured metric: 25.58 %, N_cells = 728
Starting iteration no. 21, captured metric: 26.14 %, N_cells = 755
Starting iteration no. 22, captured metric: 26.75 %, N_cells = 782
Starting iteration no. 23, captured metric: 27.54 %, N_cells = 809
Starting iteration no. 24, captured metric: 27.94 %, N_cells = 836
Starting iteration no. 25, captured metric: 28.2 %, N_cells = 863
Starting iteration no. 26, captured metric: 28.54 %, N_cells = 890
Starting iteration no. 27, captured metric: 28.97 %, N_cells = 917
Starting iteration no. 28, captured metric: 29.42 %, N_cells = 944
Starting iteration no. 29, captured metric: 29.78 %, N_cells = 971
Starting iteration no. 30, captured metric: 30.16 %, N_cells = 998
Starting iteration no. 31, captured metric: 30.78 %, N_cells = 1025
Starting iteration no. 32, captured metric: 31.05 %, N_cells = 1052
Starting iteration no. 33, captured metric: 31.18 %, N_cells = 1079
Starting iteration no. 34, captured metric: 31.5 %, N_cells = 1106
Starting iteration no. 35, captured metric: 31.74 %, N_cells = 1133
Starting iteration no. 36, captured metric: 32.06 %, N_cells = 1160
Starting iteration no. 37, captured metric: 32.36 %, N_cells = 1187
Starting iteration no. 38, captured metric: 32.66 %, N_cells = 1214
Starting iteration no. 39, captured metric: 32.76 %, N_cells = 1241
Starting iteration no. 40, captured metric: 32.79 %, N_cells = 1268
Starting iteration no. 41, captured metric: 32.93 %, N_cells = 1295
Starting iteration no. 42, captured metric: 33.13 %, N_cells = 1322
Starting iteration no. 43, captured metric: 33.47 %, N_cells = 1349
Starting iteration no. 44, captured metric: 33.61 %, N_cells = 1376
Starting iteration no. 45, captured metric: 33.93 %, N_cells = 1403
Starting iteration no. 46, captured metric: 34.09 %, N_cells = 1430
Starting iteration no. 47, captured metric: 34.18 %, N_cells = 1457
Starting iteration no. 48, captured metric: 34.44 %, N_cells = 1484
Starting iteration no. 49, captured metric: 34.57 %, N_cells = 1511
Starting iteration no. 50, captured metric: 34.72 %, N_cells = 1538
Starting iteration no. 51, captured metric: 35.12 %, N_cells = 1565
Starting iteration no. 52, captured metric: 35.46 %, N_cells = 1592
Starting iteration no. 53, captured metric: 35.7 %, N_cells = 1619
Starting iteration no. 54, captured metric: 35.94 %, N_cells = 1646
Starting iteration no. 55, captured metric: 36.14 %, N_cells = 1673
Starting iteration no. 56, captured metric: 36.28 %, N_cells = 1700
Starting iteration no. 57, captured metric: 36.52 %, N_cells = 1727
Starting iteration no. 58, captured metric: 36.85 %, N_cells = 1754
Starting iteration no. 59, captured metric: 37.1 %, N_cells = 1781
Starting iteration no. 60, captured metric: 37.4 %, N_cells = 1808
Starting iteration no. 61, captured metric: 37.75 %, N_cells = 1835
Starting iteration no. 62, captured metric: 38.0 %, N_cells = 1862
Starting iteration no. 63, captured metric: 38.21 %, N_cells = 1889
Starting iteration no. 64, captured metric: 38.51 %, N_cells = 1916
Starting iteration no. 65, captured metric: 38.85 %, N_cells = 1943
Starting iteration no. 66, captured metric: 39.13 %, N_cells = 1970
Starting iteration no. 67, captured metric: 39.34 %, N_cells = 1997
Starting iteration no. 68, captured metric: 39.8 %, N_cells = 2024
Starting iteration no. 69, captured metric: 40.03 %, N_cells = 2051
Starting iteration no. 70, captured metric: 40.27 %, N_cells = 2078
Starting iteration no. 71, captured metric: 40.59 %, N_cells = 2105
Starting iteration no. 72, captured metric: 40.92 %, N_cells = 2132
Starting iteration no. 73, captured metric: 41.27 %, N_cells = 2159
Starting iteration no. 74, captured metric: 41.63 %, N_cells = 2186
Starting iteration no. 75, captured metric: 41.94 %, N_cells = 2212
Starting iteration no. 76, captured metric: 42.3 %, N_cells = 2239
Starting iteration no. 77, captured metric: 42.7 %, N_cells = 2266
Starting iteration no. 78, captured metric: 43.05 %, N_cells = 2293
Starting iteration no. 79, captured metric: 43.43 %, N_cells = 2320
Starting iteration no. 80, captured metric: 43.71 %, N_cells = 2347
Starting iteration no. 81, captured metric: 44.12 %, N_cells = 2374
Starting iteration no. 82, captured metric: 44.52 %, N_cells = 2401
Starting iteration no. 83, captured metric: 44.81 %, N_cells = 2428
Starting iteration no. 84, captured metric: 45.19 %, N_cells = 2455
Starting iteration no. 85, captured metric: 45.59 %, N_cells = 2482
Starting iteration no. 86, captured metric: 46.0 %, N_cells = 2509
Starting iteration no. 87, captured metric: 46.38 %, N_cells = 2536
Starting iteration no. 88, captured metric: 46.73 %, N_cells = 2563
Starting iteration no. 89, captured metric: 47.13 %, N_cells = 2590
Starting iteration no. 90, captured metric: 47.54 %, N_cells = 2617
Starting iteration no. 91, captured metric: 47.91 %, N_cells = 2644
Starting iteration no. 92, captured metric: 48.3 %, N_cells = 2671
Starting iteration no. 93, captured metric: 48.57 %, N_cells = 2698
Starting iteration no. 94, captured metric: 48.92 %, N_cells = 2725
Starting iteration no. 95, captured metric: 49.24 %, N_cells = 2752
Starting iteration no. 96, captured metric: 49.51 %, N_cells = 2779
Starting iteration no. 97, captured metric: 49.73 %, N_cells = 2806
Starting iteration no. 98, captured metric: 49.83 %, N_cells = 2831
[2026-02-19 15:38:43] INFO Finished metric-based refinement.
[2026-02-19 15:38:43] INFO Starting geometry refinement.
[2026-02-19 15:38:43] INFO Starting refining geometry cylinder.
[2026-02-19 15:38:43] INFO Found a minimum cell level of 6. Target level is 12.
Refining level 7 / 12.
Refining level 8 / 12.
Refining level 9 / 12.
Refining level 10 / 12.
Refining level 11 / 12.
Refining level 12 / 12.
[2026-02-19 15:38:44] INFO Finished geometry refinement.
[2026-02-19 15:38:44] INFO Starting renumbering final mesh.
[2026-02-19 15:38:47] INFO Finished refinement in 14.5280 s
(99 iterations).
Time for uniform refinement: 5.4432 s
Time for metric-based refinement: 4.8844 s
Time for geometry refinement: 1.0879 s
Time for renumbering the final mesh: 3.0965 s
Number of cells: 4301
Minimum ref. level: 6
Maximum ref. level: 12
Captured metric of original grid: 50.06 %
[2026-02-19 15:38:47] INFO Initializing KNN and computing interpolation weights.
[2026-02-19 15:38:47] INFO Starting interpolation and export of field U.
[2026-02-19 15:38:47] INFO Writing HDF5 file for field U.
[2026-02-19 15:38:47] INFO Writing XDMF file for file cylinder2D_nodeltaLevel_constraint.h5
[2026-02-19 15:38:47] INFO Finished export of field U in 0.039s.
[5]:
# now we activate the max_delta_level constraint to see how the grid quality improves
s_cube = SparseSpatialSampling(coord, metric, [domain, geometry], save_path, "cylinder2D_deltaLevel_constraint", "cylinder2D",
min_metric=0.5, n_jobs=4, max_delta_level=True)
s_cube.execute_grid_generation()
export = ExportData(s_cube, write_times="10")
export.export(coord, field[:, :, -1].unsqueeze(-1), "U")
[2026-02-19 15:38:47] INFO Selecting min. approximation of the metric as stopping criterion.
[2026-02-19 15:38:47] INFO
Selected settings:
pre_select : False
n_jobs : 4
max_delta_level : True
geometry : ['domain', 'cylinder']
min_metric : 0.5
min_level : 5
cells_per_iter_start : 9
cells_per_iter_end : 9
cells_per_iter : 9
cells_per_iter_last : 1000000000.0
reach_at_least : 0.75
n_dimensions : 2
n_cells_orig : 9800
relTol : 0.001
[2026-02-19 15:38:47] INFO Starting grid generation.
[2026-02-19 15:38:47] INFO Starting uniform refinement.
Starting iteration no. 0, N_cells = 1
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Starting iteration no. 1, N_cells = 4
Starting iteration no. 2, N_cells = 8
Starting iteration no. 3, N_cells = 16
Starting iteration no. 4, N_cells = 64
[2026-02-19 15:38:53] INFO Finished uniform refinement.
[2026-02-19 15:38:53] INFO Starting metric-based refinement.
Starting iteration no. 0, captured metric: 13.64 %, N_cells = 192
Starting iteration no. 1, captured metric: 14.5 %, N_cells = 217
Starting iteration no. 2, captured metric: 15.03 %, N_cells = 244
Starting iteration no. 3, captured metric: 15.55 %, N_cells = 271
Starting iteration no. 4, captured metric: 16.37 %, N_cells = 301
Starting iteration no. 5, captured metric: 16.61 %, N_cells = 328
Starting iteration no. 6, captured metric: 16.75 %, N_cells = 355
Starting iteration no. 7, captured metric: 16.89 %, N_cells = 382
Starting iteration no. 8, captured metric: 17.13 %, N_cells = 409
Starting iteration no. 9, captured metric: 17.68 %, N_cells = 436
Starting iteration no. 10, captured metric: 18.44 %, N_cells = 465
Starting iteration no. 11, captured metric: 19.06 %, N_cells = 492
Starting iteration no. 12, captured metric: 19.65 %, N_cells = 519
Starting iteration no. 13, captured metric: 20.38 %, N_cells = 546
Starting iteration no. 14, captured metric: 21.07 %, N_cells = 573
Starting iteration no. 15, captured metric: 21.89 %, N_cells = 603
Starting iteration no. 16, captured metric: 22.9 %, N_cells = 630
Starting iteration no. 17, captured metric: 23.77 %, N_cells = 657
Starting iteration no. 18, captured metric: 24.46 %, N_cells = 683
Starting iteration no. 19, captured metric: 25.12 %, N_cells = 710
Starting iteration no. 20, captured metric: 25.82 %, N_cells = 737
Starting iteration no. 21, captured metric: 26.35 %, N_cells = 764
Starting iteration no. 22, captured metric: 27.03 %, N_cells = 791
Starting iteration no. 23, captured metric: 27.69 %, N_cells = 818
Starting iteration no. 24, captured metric: 27.99 %, N_cells = 845
Starting iteration no. 25, captured metric: 28.35 %, N_cells = 872
Starting iteration no. 26, captured metric: 28.74 %, N_cells = 899
Starting iteration no. 27, captured metric: 29.16 %, N_cells = 926
Starting iteration no. 28, captured metric: 29.71 %, N_cells = 956
Starting iteration no. 29, captured metric: 30.24 %, N_cells = 983
Starting iteration no. 30, captured metric: 30.81 %, N_cells = 1013
Starting iteration no. 31, captured metric: 31.25 %, N_cells = 1040
Starting iteration no. 32, captured metric: 31.46 %, N_cells = 1067
Starting iteration no. 33, captured metric: 31.52 %, N_cells = 1094
Starting iteration no. 34, captured metric: 31.7 %, N_cells = 1121
Starting iteration no. 35, captured metric: 32.11 %, N_cells = 1148
Starting iteration no. 36, captured metric: 32.36 %, N_cells = 1175
Starting iteration no. 37, captured metric: 32.56 %, N_cells = 1202
Starting iteration no. 38, captured metric: 32.67 %, N_cells = 1229
Starting iteration no. 39, captured metric: 32.77 %, N_cells = 1256
Starting iteration no. 40, captured metric: 32.83 %, N_cells = 1283
Starting iteration no. 41, captured metric: 33.26 %, N_cells = 1313
Starting iteration no. 42, captured metric: 33.34 %, N_cells = 1340
Starting iteration no. 43, captured metric: 33.65 %, N_cells = 1367
Starting iteration no. 44, captured metric: 33.93 %, N_cells = 1394
Starting iteration no. 45, captured metric: 34.12 %, N_cells = 1421
Starting iteration no. 46, captured metric: 34.27 %, N_cells = 1448
Starting iteration no. 47, captured metric: 34.38 %, N_cells = 1475
Starting iteration no. 48, captured metric: 34.66 %, N_cells = 1502
Starting iteration no. 49, captured metric: 34.82 %, N_cells = 1529
Starting iteration no. 50, captured metric: 35.04 %, N_cells = 1556
Starting iteration no. 51, captured metric: 35.39 %, N_cells = 1583
Starting iteration no. 52, captured metric: 35.74 %, N_cells = 1610
Starting iteration no. 53, captured metric: 35.92 %, N_cells = 1637
Starting iteration no. 54, captured metric: 36.11 %, N_cells = 1664
Starting iteration no. 55, captured metric: 36.27 %, N_cells = 1691
Starting iteration no. 56, captured metric: 36.42 %, N_cells = 1718
Starting iteration no. 57, captured metric: 36.68 %, N_cells = 1745
Starting iteration no. 58, captured metric: 37.05 %, N_cells = 1772
Starting iteration no. 59, captured metric: 37.33 %, N_cells = 1799
Starting iteration no. 60, captured metric: 37.62 %, N_cells = 1826
Starting iteration no. 61, captured metric: 37.91 %, N_cells = 1853
Starting iteration no. 62, captured metric: 38.12 %, N_cells = 1880
Starting iteration no. 63, captured metric: 38.46 %, N_cells = 1907
Starting iteration no. 64, captured metric: 38.71 %, N_cells = 1934
Starting iteration no. 65, captured metric: 39.07 %, N_cells = 1961
Starting iteration no. 66, captured metric: 39.23 %, N_cells = 1988
Starting iteration no. 67, captured metric: 39.72 %, N_cells = 2015
Starting iteration no. 68, captured metric: 39.95 %, N_cells = 2042
Starting iteration no. 69, captured metric: 40.17 %, N_cells = 2069
Starting iteration no. 70, captured metric: 40.48 %, N_cells = 2096
Starting iteration no. 71, captured metric: 40.84 %, N_cells = 2123
Starting iteration no. 72, captured metric: 41.15 %, N_cells = 2150
Starting iteration no. 73, captured metric: 41.5 %, N_cells = 2177
Starting iteration no. 74, captured metric: 41.86 %, N_cells = 2204
Starting iteration no. 75, captured metric: 42.17 %, N_cells = 2230
Starting iteration no. 76, captured metric: 42.59 %, N_cells = 2257
Starting iteration no. 77, captured metric: 42.94 %, N_cells = 2284
Starting iteration no. 78, captured metric: 43.3 %, N_cells = 2311
Starting iteration no. 79, captured metric: 43.63 %, N_cells = 2338
Starting iteration no. 80, captured metric: 44.03 %, N_cells = 2365
Starting iteration no. 81, captured metric: 44.38 %, N_cells = 2392
Starting iteration no. 82, captured metric: 44.69 %, N_cells = 2419
Starting iteration no. 83, captured metric: 45.06 %, N_cells = 2446
Starting iteration no. 84, captured metric: 45.45 %, N_cells = 2473
Starting iteration no. 85, captured metric: 45.86 %, N_cells = 2500
Starting iteration no. 86, captured metric: 46.3 %, N_cells = 2527
Starting iteration no. 87, captured metric: 46.61 %, N_cells = 2554
Starting iteration no. 88, captured metric: 47.02 %, N_cells = 2581
Starting iteration no. 89, captured metric: 47.41 %, N_cells = 2608
Starting iteration no. 90, captured metric: 47.77 %, N_cells = 2635
Starting iteration no. 91, captured metric: 48.18 %, N_cells = 2662
Starting iteration no. 92, captured metric: 48.51 %, N_cells = 2689
Starting iteration no. 93, captured metric: 48.83 %, N_cells = 2716
Starting iteration no. 94, captured metric: 49.14 %, N_cells = 2743
Starting iteration no. 95, captured metric: 49.39 %, N_cells = 2770
Starting iteration no. 96, captured metric: 49.62 %, N_cells = 2797
Starting iteration no. 97, captured metric: 49.79 %, N_cells = 2822
Starting iteration no. 98, captured metric: 49.96 %, N_cells = 2849
[2026-02-19 15:38:58] INFO Finished metric-based refinement.
[2026-02-19 15:38:58] INFO Starting geometry refinement.
[2026-02-19 15:38:58] INFO Starting refining geometry cylinder.
[2026-02-19 15:38:58] INFO Found a minimum cell level of 6. Target level is 12.
Refining level 7 / 12.
Refining level 8 / 12.
Refining level 9 / 12.
Refining level 10 / 12.
Refining level 11 / 12.
Refining level 12 / 12.
[2026-02-19 15:38:59] INFO Finished geometry refinement.
[2026-02-19 15:38:59] INFO Starting renumbering final mesh.
[2026-02-19 15:38:59] INFO Finished refinement in 11.5554 s
(99 iterations).
Time for uniform refinement: 5.0861 s
Time for metric-based refinement: 5.0659 s
Time for geometry refinement: 1.3162 s
Time for renumbering the final mesh: 0.0720 s
Number of cells: 5891
Minimum ref. level: 6
Maximum ref. level: 12
Captured metric of original grid: 50.18 %
[2026-02-19 15:38:59] INFO Initializing KNN and computing interpolation weights.
[2026-02-19 15:38:59] INFO Starting interpolation and export of field U.
[2026-02-19 15:38:59] INFO Writing HDF5 file for field U.
[2026-02-19 15:38:59] INFO Writing XDMF file for file cylinder2D_deltaLevel_constraint.h5
[2026-02-19 15:38:59] INFO Finished export of field U in 0.041s.
As already discussed in the introduction, we can see that the number of cells increased from \(4301\) to \(5891\) when activating the constraint. Now let’s load the data into ParaView and compare the grids.
First we take a look at the grid without the constraint:
Here, we can already see large level differences at the domain boundaries and near the cylinder. We can zoom in the region near the cylinder to see it better:
As explained, these differences within the cell size can cause problems, e.g. when computing gradients on that grid. As a comparison we can now take a look athe the grid which was created with the delta level constraint:
When we zoom in the same region as before we can see that the grid quality improved significantly:
2. Controlling the uniformity of the grid
The next parameter we want to look at is uniform_levels, which controls the number of uniform grid levels. \(S^3\) starts by creating a uniform background grid before starting the adaptive refinement in order to accelerate the grid generation process.
A rule of thumb is: when increasing the number uniform levels, the grid will become more uniform but the execution time decreases and vice versa. In general it is only sensible to adjust this parameter if the grid is expected to be very coarse (then uniform_levels has to be decreased), or if the number of grid levels is expected to be large. In the latter case, the number of uniform levels can be increased.
Since this parameter is quite intuitive, we will briefly show what happens if it gets increased in the following.
[6]:
# execute for higher n_uniform levels
# The default is 5 uniform levels, but the min_level is already 6 so we don't expect the grid to be adaptive
s_cube = SparseSpatialSampling(coord, metric, [domain, geometry], save_path, "cylinder2D_6_uniform_levels", "cylinder2D",
min_metric=0.5, n_jobs=4, uniform_levels=7)
s_cube.execute_grid_generation()
# export
export = ExportData(s_cube, write_times="10")
export.export(coord, field[:, :, -1].unsqueeze(-1), "U")
[2026-02-19 15:38:59] INFO Selecting min. approximation of the metric as stopping criterion.
[2026-02-19 15:38:59] INFO
Selected settings:
pre_select : False
n_jobs : 4
max_delta_level : False
geometry : ['domain', 'cylinder']
min_metric : 0.5
min_level : 7
cells_per_iter_start : 9
cells_per_iter_end : 9
cells_per_iter : 9
cells_per_iter_last : 1000000000.0
reach_at_least : 0.75
n_dimensions : 2
n_cells_orig : 9800
relTol : 0.001
[2026-02-19 15:38:59] INFO Starting grid generation.
[2026-02-19 15:38:59] INFO Starting uniform refinement.
Starting iteration no. 0, N_cells = 1
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Warning: TecplotDataloader can't be loaded. Most likely, the 'paraview' module is missing.
Refer to the installation instructions at https://github.com/FlowModelingControl/flowtorch
If you are not using the TecplotDataloader, ignore this warning.
Starting iteration no. 1, N_cells = 4
Starting iteration no. 2, N_cells = 8
Starting iteration no. 3, N_cells = 16
Starting iteration no. 4, N_cells = 64
Starting iteration no. 5, N_cells = 192
Starting iteration no. 6, N_cells = 766
[2026-02-19 15:39:05] INFO Finished uniform refinement.
[2026-02-19 15:39:05] INFO Starting metric-based refinement.
Starting iteration no. 0, captured metric: 54.73 %, N_cells = 3056
[2026-02-19 15:39:05] INFO Finished metric-based refinement.
[2026-02-19 15:39:05] INFO Starting geometry refinement.
[2026-02-19 15:39:05] INFO Starting refining geometry cylinder.
[2026-02-19 15:39:05] INFO Found a minimum cell level of 7. Target level is 12.
Refining level 8 / 12.
Refining level 9 / 12.
Refining level 10 / 12.
Refining level 11 / 12.
Refining level 12 / 12.
[2026-02-19 15:39:06] INFO Finished geometry refinement.
[2026-02-19 15:39:06] INFO Starting renumbering final mesh.
[2026-02-19 15:39:06] INFO Finished refinement in 7.1241 s
(1 iterations).
Time for uniform refinement: 6.0477 s
Time for metric-based refinement: 0.0646 s
Time for geometry refinement: 0.8870 s
Time for renumbering the final mesh: 0.1054 s
Number of cells: 4538
Minimum ref. level: 7
Maximum ref. level: 12
Captured metric of original grid: 55.06 %
[2026-02-19 15:39:06] INFO Initializing KNN and computing interpolation weights.
[2026-02-19 15:39:06] INFO Starting interpolation and export of field U.
[2026-02-19 15:39:06] INFO Writing HDF5 file for field U.
[2026-02-19 15:39:06] INFO Writing XDMF file for file cylinder2D_6_uniform_levels.h5
[2026-02-19 15:39:06] INFO Finished export of field U in 0.041s.
As we expected, the resulting grid is much more uniform than the grid using the default value of uniform_levels=5:
This happens because our grid using uniform_levels=5 has a minimum refinement level of \(6\). So if we increase uniform_levelsto \(7\) the adaptive refinement is never activated.
3. Accelerating the refinement process for large 3D datasets
For large grids and in case STL file(s) are used as geometry objects, there are three more parameters which we can adjust in order to accelerate the refienment process. However, since our cylinder2D test case is too simple to see an actual effect, we will just explain the usage of these parameters briefly in the following.
The first two parameters are n_cells_iter_start and n_cells_iter_end. These parameters control how many cells are generated each iteration. By default n_cells_iter_start=0.001 n_cells_original_grid with n_cells_original_grid denoting the number of cells in the mesh from the simulation and n_cells_iter_end = n_cells_iter_start. Each iteration, the number of cells to refine is computed based on properties of the current grid.
When increasing n_cells_iter_start and/or n_cells_iter_end, this leads to generating more cells per iteration and therefore a more uniform grid. Decreasing them analogously leads to a more adaptive grid, however, it also increases the runtime of \(S^3\). In general, these parameters have a more complex influence on the runtime and resulting grid than, e.g., uniform_levels, so usually it should be avoided to modify them. But it may be helpful in some special cases.
The last parameter is pre_select, which is useful when STL files are used as geometry objects. Especially if the expected number of grid points is large and the STL file has a high resolution (contains many points). To accelerate the grid generation, the class GeometrySTL3D provides an additional parameter reduce_by, which compresses the STL file by \(x\%\). The optimal compression ratio depends on the application, but values up to reduce_by=0.9 generally shouldn’t cause any
problems. If that is still not able to decrease the required runtime significantly, the parameter pre_selectcan be set to True when instantiating the s_cube object. Since this parameter determines possible cells in the vicinity of the geometry much faster than the ‘standard’ way when dealing with STL files, this can significantly accelerate the refinement process.
Note: The parameter pre_select works best if the edges of a box drawn around the STL file have nearly the same length, meaning that the shape of the STL file is nearly cubic. For STL files which have a dominant length, e.g. aircraft with high aspect ratio wings, setting pre_select=True may even increase the required runtime!
This concludes the third tutorial. The next tutorial presents different options when exporting the data to HDF5.
[6]: