Tutorial 3: How to select the best settings and advanced options

flowTorch workshop 29.09.2025 - 02.10.2025

Outline

  1. Avoid large size differences between neighboring cells

  2. Controlling the uniformity of the grid

  3. 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 numpy as np
import torch as pt

from os.path import join
from os import environ, system

environ["sparseSpatialSampling"] = "../../.."
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)
[2025-08-15 14:31:07] INFO     Loading precomputed cell centers and volumes from processor0/constant
[2025-08-15 14:31:07] 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)
export.write_times = "10"
export.export(coord, field[:, :, -1].unsqueeze(-1), "U")
[2025-08-15 14:31:11] INFO
        Selected settings:
                _pre_select          :  False
                _n_jobs              :  4
                _max_delta_level     :  False
                _geometry            :  ['domain', 'cylinder']
                _min_metric          :  0.5
                _n_cells_max         :  None
                _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
[2025-08-15 14:31:11] INFO     Starting refinement:
        Starting iteration no. 0, N_cells = 1
        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
[2025-08-15 14:31:16] INFO     Finished uniform refinement.
[2025-08-15 14:31:16] INFO     Starting adaptive refinement.
        Starting iteration no. 0, captured metric: 13.74 %, N_cells = 256
        Starting iteration no. 1, captured metric: 14.58 %, N_cells = 281
        Starting iteration no. 2, captured metric: 15.17 %, N_cells = 308
        Starting iteration no. 3, captured metric: 15.45 %, N_cells = 335
        Starting iteration no. 4, captured metric: 16.3 %, N_cells = 362
        Starting iteration no. 5, captured metric: 16.55 %, N_cells = 389
        Starting iteration no. 6, captured metric: 16.8 %, N_cells = 416
        Starting iteration no. 7, captured metric: 16.95 %, N_cells = 443
        Starting iteration no. 8, captured metric: 17.09 %, N_cells = 470
        Starting iteration no. 9, captured metric: 17.7 %, N_cells = 497
        Starting iteration no. 10, captured metric: 18.6 %, N_cells = 523
        Starting iteration no. 11, captured metric: 19.22 %, N_cells = 550
        Starting iteration no. 12, captured metric: 19.87 %, N_cells = 577
        Starting iteration no. 13, captured metric: 20.6 %, N_cells = 604
        Starting iteration no. 14, captured metric: 21.18 %, N_cells = 631
        Starting iteration no. 15, captured metric: 21.87 %, N_cells = 657
        Starting iteration no. 16, captured metric: 22.82 %, N_cells = 684
        Starting iteration no. 17, captured metric: 23.75 %, N_cells = 711
        Starting iteration no. 18, captured metric: 24.45 %, N_cells = 737
        Starting iteration no. 19, captured metric: 25.24 %, N_cells = 764
        Starting iteration no. 20, captured metric: 25.8 %, N_cells = 791
        Starting iteration no. 21, captured metric: 26.37 %, N_cells = 818
        Starting iteration no. 22, captured metric: 26.99 %, N_cells = 845
        Starting iteration no. 23, captured metric: 27.53 %, N_cells = 872
        Starting iteration no. 24, captured metric: 28.19 %, N_cells = 899
        Starting iteration no. 25, captured metric: 28.57 %, N_cells = 926
        Starting iteration no. 26, captured metric: 28.95 %, N_cells = 953
        Starting iteration no. 27, captured metric: 29.27 %, N_cells = 980
        Starting iteration no. 28, captured metric: 29.65 %, N_cells = 1007
        Starting iteration no. 29, captured metric: 30.05 %, N_cells = 1034
        Starting iteration no. 30, captured metric: 30.43 %, N_cells = 1061
        Starting iteration no. 31, captured metric: 30.61 %, N_cells = 1088
        Starting iteration no. 32, captured metric: 30.94 %, N_cells = 1115
        Starting iteration no. 33, captured metric: 31.37 %, N_cells = 1142
        Starting iteration no. 34, captured metric: 31.71 %, N_cells = 1169
        Starting iteration no. 35, captured metric: 32.12 %, N_cells = 1196
        Starting iteration no. 36, captured metric: 32.49 %, N_cells = 1223
        Starting iteration no. 37, captured metric: 32.72 %, N_cells = 1250
        Starting iteration no. 38, captured metric: 32.79 %, N_cells = 1277
        Starting iteration no. 39, captured metric: 32.89 %, N_cells = 1304
        Starting iteration no. 40, captured metric: 33.03 %, N_cells = 1325
        Starting iteration no. 41, captured metric: 33.29 %, N_cells = 1352
        Starting iteration no. 42, captured metric: 33.8 %, N_cells = 1379
        Starting iteration no. 43, captured metric: 33.93 %, N_cells = 1406
        Starting iteration no. 44, captured metric: 34.19 %, N_cells = 1433
        Starting iteration no. 45, captured metric: 34.36 %, N_cells = 1456
        Starting iteration no. 46, captured metric: 34.58 %, N_cells = 1481
        Starting iteration no. 47, captured metric: 34.81 %, N_cells = 1508
        Starting iteration no. 48, captured metric: 34.98 %, N_cells = 1535
        Starting iteration no. 49, captured metric: 35.12 %, N_cells = 1562
        Starting iteration no. 50, captured metric: 35.38 %, N_cells = 1589
        Starting iteration no. 51, captured metric: 35.55 %, N_cells = 1616
        Starting iteration no. 52, captured metric: 35.66 %, N_cells = 1643
        Starting iteration no. 53, captured metric: 35.82 %, N_cells = 1670
        Starting iteration no. 54, captured metric: 35.96 %, N_cells = 1695
        Starting iteration no. 55, captured metric: 36.21 %, N_cells = 1722
        Starting iteration no. 56, captured metric: 36.32 %, N_cells = 1749
        Starting iteration no. 57, captured metric: 36.7 %, N_cells = 1776
        Starting iteration no. 58, captured metric: 37.05 %, N_cells = 1803
        Starting iteration no. 59, captured metric: 37.22 %, N_cells = 1830
        Starting iteration no. 60, captured metric: 37.52 %, N_cells = 1857
        Starting iteration no. 61, captured metric: 37.89 %, N_cells = 1880
        Starting iteration no. 62, captured metric: 38.16 %, N_cells = 1907
        Starting iteration no. 63, captured metric: 38.51 %, N_cells = 1934
        Starting iteration no. 64, captured metric: 38.86 %, N_cells = 1961
        Starting iteration no. 65, captured metric: 39.11 %, N_cells = 1988
        Starting iteration no. 66, captured metric: 39.32 %, N_cells = 2015
        Starting iteration no. 67, captured metric: 39.5 %, N_cells = 2040
        Starting iteration no. 68, captured metric: 39.79 %, N_cells = 2065
        Starting iteration no. 69, captured metric: 40.04 %, N_cells = 2092
        Starting iteration no. 70, captured metric: 40.28 %, N_cells = 2119
        Starting iteration no. 71, captured metric: 40.61 %, N_cells = 2146
        Starting iteration no. 72, captured metric: 40.89 %, N_cells = 2169
        Starting iteration no. 73, captured metric: 41.16 %, N_cells = 2194
        Starting iteration no. 74, captured metric: 41.48 %, N_cells = 2221
        Starting iteration no. 75, captured metric: 41.8 %, N_cells = 2248
        Starting iteration no. 76, captured metric: 42.17 %, N_cells = 2275
        Starting iteration no. 77, captured metric: 42.47 %, N_cells = 2300
        Starting iteration no. 78, captured metric: 42.8 %, N_cells = 2327
        Starting iteration no. 79, captured metric: 43.22 %, N_cells = 2354
        Starting iteration no. 80, captured metric: 43.5 %, N_cells = 2379
        Starting iteration no. 81, captured metric: 43.8 %, N_cells = 2404
        Starting iteration no. 82, captured metric: 44.12 %, N_cells = 2431
        Starting iteration no. 83, captured metric: 44.42 %, N_cells = 2456
        Starting iteration no. 84, captured metric: 44.8 %, N_cells = 2481
        Starting iteration no. 85, captured metric: 45.08 %, N_cells = 2506
        Starting iteration no. 86, captured metric: 45.44 %, N_cells = 2533
        Starting iteration no. 87, captured metric: 45.72 %, N_cells = 2558
        Starting iteration no. 88, captured metric: 45.9 %, N_cells = 2575
        Starting iteration no. 89, captured metric: 46.23 %, N_cells = 2600
        Starting iteration no. 90, captured metric: 46.58 %, N_cells = 2623
        Starting iteration no. 91, captured metric: 46.96 %, N_cells = 2648
        Starting iteration no. 92, captured metric: 47.3 %, N_cells = 2673
        Starting iteration no. 93, captured metric: 47.64 %, N_cells = 2698
        Starting iteration no. 94, captured metric: 47.93 %, N_cells = 2723
        Starting iteration no. 95, captured metric: 48.33 %, N_cells = 2750
        Starting iteration no. 96, captured metric: 48.67 %, N_cells = 2775
        Starting iteration no. 97, captured metric: 48.89 %, N_cells = 2798
        Starting iteration no. 98, captured metric: 49.2 %, N_cells = 2821
        Starting iteration no. 99, captured metric: 49.43 %, N_cells = 2844
        Starting iteration no. 100, captured metric: 49.66 %, N_cells = 2869
        Starting iteration no. 101, captured metric: 49.78 %, N_cells = 2890
[2025-08-15 14:31:21] INFO     Finished adaptive refinement.
[2025-08-15 14:31:21] INFO     Starting geometry refinement.
[2025-08-15 14:31:21] INFO     Starting refining geometry cylinder.
[2025-08-15 14:31:22] INFO     Finished geometry refinement.
[2025-08-15 14:31:22] INFO     Starting renumbering final mesh.
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.
[2025-08-15 14:31:26] INFO     Finished refinement in 14.3668 s
                                                                (102 iterations).
                                                                Time for uniform refinement: 4.9637 s
                                                                Time for adaptive refinement: 4.3591 s
                                                                Time for geometry refinement: 0.9209 s
                                                                Time for renumbering the final mesh: 4.1085 s

                                    Number of cells: 4370
                                    Minimum ref. level: 5
                                    Maximum ref. level: 12
                                    Captured metric of original grid: 50.08 %

[2025-08-15 14:31:26] INFO     Starting interpolation and export of field U.
[2025-08-15 14:31:26] INFO     Writing HDF5 file for field U.
[2025-08-15 14:31:26] INFO     Writing XDMF file for file cylinder2D_nodeltaLevel_constraint.h5
[2025-08-15 14:31:26] INFO     Finished export of field U in 0.104s.
[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)
export.write_times = "10"
export.export(coord, field[:, :, -1].unsqueeze(-1), "U")
[2025-08-15 14:31:26] INFO
        Selected settings:
                _pre_select          :  False
                _n_jobs              :  4
                _max_delta_level     :  True
                _geometry            :  ['domain', 'cylinder']
                _min_metric          :  0.5
                _n_cells_max         :  None
                _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
[2025-08-15 14:31:26] INFO     Starting refinement:
        Starting iteration no. 0, N_cells = 1
        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
[2025-08-15 14:31:31] INFO     Finished uniform refinement.
[2025-08-15 14:31:31] INFO     Starting adaptive refinement.
        Starting iteration no. 0, captured metric: 13.74 %, N_cells = 256
        Starting iteration no. 1, captured metric: 14.58 %, N_cells = 281
        Starting iteration no. 2, captured metric: 15.17 %, N_cells = 308
        Starting iteration no. 3, captured metric: 15.45 %, N_cells = 335
        Starting iteration no. 4, captured metric: 16.55 %, N_cells = 368
        Starting iteration no. 5, captured metric: 16.79 %, N_cells = 395
        Starting iteration no. 6, captured metric: 17.05 %, N_cells = 422
        Starting iteration no. 7, captured metric: 17.19 %, N_cells = 449
        Starting iteration no. 8, captured metric: 17.33 %, N_cells = 476
        Starting iteration no. 9, captured metric: 17.99 %, N_cells = 503
        Starting iteration no. 10, captured metric: 18.86 %, N_cells = 535
        Starting iteration no. 11, captured metric: 19.47 %, N_cells = 562
        Starting iteration no. 12, captured metric: 20.12 %, N_cells = 589
        Starting iteration no. 13, captured metric: 20.8 %, N_cells = 616
        Starting iteration no. 14, captured metric: 21.39 %, N_cells = 643
        Starting iteration no. 15, captured metric: 22.18 %, N_cells = 669
        Starting iteration no. 16, captured metric: 23.12 %, N_cells = 696
        Starting iteration no. 17, captured metric: 24.05 %, N_cells = 723
        Starting iteration no. 18, captured metric: 24.73 %, N_cells = 751
        Starting iteration no. 19, captured metric: 25.47 %, N_cells = 779
        Starting iteration no. 20, captured metric: 26.12 %, N_cells = 810
        Starting iteration no. 21, captured metric: 26.61 %, N_cells = 839
        Starting iteration no. 22, captured metric: 27.21 %, N_cells = 867
        Starting iteration no. 23, captured metric: 27.88 %, N_cells = 894
        Starting iteration no. 24, captured metric: 28.29 %, N_cells = 922
        Starting iteration no. 25, captured metric: 28.64 %, N_cells = 952
        Starting iteration no. 26, captured metric: 29.05 %, N_cells = 979
        Starting iteration no. 27, captured metric: 29.42 %, N_cells = 1007
        Starting iteration no. 28, captured metric: 30.15 %, N_cells = 1042
        Starting iteration no. 29, captured metric: 30.56 %, N_cells = 1070
        Starting iteration no. 30, captured metric: 30.82 %, N_cells = 1100
        Starting iteration no. 31, captured metric: 31.13 %, N_cells = 1128
        Starting iteration no. 32, captured metric: 31.54 %, N_cells = 1161
        Starting iteration no. 33, captured metric: 31.85 %, N_cells = 1188
        Starting iteration no. 34, captured metric: 32.03 %, N_cells = 1223
        Starting iteration no. 35, captured metric: 32.41 %, N_cells = 1252
        Starting iteration no. 36, captured metric: 32.55 %, N_cells = 1279
        Starting iteration no. 37, captured metric: 32.79 %, N_cells = 1310
        Starting iteration no. 38, captured metric: 32.87 %, N_cells = 1340
        Starting iteration no. 39, captured metric: 33.03 %, N_cells = 1365
        Starting iteration no. 40, captured metric: 33.29 %, N_cells = 1393
        Starting iteration no. 41, captured metric: 33.55 %, N_cells = 1422
        Starting iteration no. 42, captured metric: 33.98 %, N_cells = 1453
        Starting iteration no. 43, captured metric: 34.22 %, N_cells = 1482
        Starting iteration no. 44, captured metric: 34.44 %, N_cells = 1510
        Starting iteration no. 45, captured metric: 34.67 %, N_cells = 1533
        Starting iteration no. 46, captured metric: 34.93 %, N_cells = 1560
        Starting iteration no. 47, captured metric: 35.11 %, N_cells = 1587
        Starting iteration no. 48, captured metric: 35.19 %, N_cells = 1614
        Starting iteration no. 49, captured metric: 35.48 %, N_cells = 1641
        Starting iteration no. 50, captured metric: 35.65 %, N_cells = 1668
        Starting iteration no. 51, captured metric: 35.76 %, N_cells = 1695
        Starting iteration no. 52, captured metric: 35.87 %, N_cells = 1722
        Starting iteration no. 53, captured metric: 36.08 %, N_cells = 1749
        Starting iteration no. 54, captured metric: 36.24 %, N_cells = 1776
        Starting iteration no. 55, captured metric: 36.43 %, N_cells = 1803
        Starting iteration no. 56, captured metric: 36.71 %, N_cells = 1830
        Starting iteration no. 57, captured metric: 36.97 %, N_cells = 1857
        Starting iteration no. 58, captured metric: 37.23 %, N_cells = 1884
        Starting iteration no. 59, captured metric: 37.49 %, N_cells = 1911
        Starting iteration no. 60, captured metric: 37.93 %, N_cells = 1938
        Starting iteration no. 61, captured metric: 38.19 %, N_cells = 1965
        Starting iteration no. 62, captured metric: 38.54 %, N_cells = 1992
        Starting iteration no. 63, captured metric: 38.91 %, N_cells = 2019
        Starting iteration no. 64, captured metric: 39.14 %, N_cells = 2046
        Starting iteration no. 65, captured metric: 39.35 %, N_cells = 2073
        Starting iteration no. 66, captured metric: 39.59 %, N_cells = 2100
        Starting iteration no. 67, captured metric: 39.86 %, N_cells = 2127
        Starting iteration no. 68, captured metric: 40.1 %, N_cells = 2154
        Starting iteration no. 69, captured metric: 40.38 %, N_cells = 2181
        Starting iteration no. 70, captured metric: 40.76 %, N_cells = 2208
        Starting iteration no. 71, captured metric: 41.06 %, N_cells = 2235
        Starting iteration no. 72, captured metric: 41.37 %, N_cells = 2262
        Starting iteration no. 73, captured metric: 41.69 %, N_cells = 2289
        Starting iteration no. 74, captured metric: 42.04 %, N_cells = 2316
        Starting iteration no. 75, captured metric: 42.4 %, N_cells = 2343
        Starting iteration no. 76, captured metric: 42.77 %, N_cells = 2370
        Starting iteration no. 77, captured metric: 43.13 %, N_cells = 2397
        Starting iteration no. 78, captured metric: 43.47 %, N_cells = 2424
        Starting iteration no. 79, captured metric: 43.8 %, N_cells = 2451
        Starting iteration no. 80, captured metric: 44.13 %, N_cells = 2478
        Starting iteration no. 81, captured metric: 44.47 %, N_cells = 2505
        Starting iteration no. 82, captured metric: 44.89 %, N_cells = 2532
        Starting iteration no. 83, captured metric: 45.23 %, N_cells = 2559
        Starting iteration no. 84, captured metric: 45.51 %, N_cells = 2586
        Starting iteration no. 85, captured metric: 45.9 %, N_cells = 2613
        Starting iteration no. 86, captured metric: 46.29 %, N_cells = 2640
        Starting iteration no. 87, captured metric: 46.73 %, N_cells = 2667
        Starting iteration no. 88, captured metric: 47.16 %, N_cells = 2694
        Starting iteration no. 89, captured metric: 47.5 %, N_cells = 2721
        Starting iteration no. 90, captured metric: 47.84 %, N_cells = 2748
        Starting iteration no. 91, captured metric: 48.24 %, N_cells = 2775
        Starting iteration no. 92, captured metric: 48.62 %, N_cells = 2802
        Starting iteration no. 93, captured metric: 48.94 %, N_cells = 2829
        Starting iteration no. 94, captured metric: 49.32 %, N_cells = 2856
        Starting iteration no. 95, captured metric: 49.61 %, N_cells = 2885
        Starting iteration no. 96, captured metric: 49.78 %, N_cells = 2914
[2025-08-15 14:31:35] INFO     Finished adaptive refinement.
[2025-08-15 14:31:35] INFO     Starting geometry refinement.
[2025-08-15 14:31:35] INFO     Starting refining geometry cylinder.
[2025-08-15 14:31:37] INFO     Finished geometry refinement.
[2025-08-15 14:31:37] INFO     Starting renumbering final mesh.
[2025-08-15 14:31:37] INFO     Finished refinement in 10.9320 s
                                                                (97 iterations).
                                                                Time for uniform refinement: 4.9321 s
                                                                Time for adaptive refinement: 4.2694 s
                                                                Time for geometry refinement: 1.6193 s
                                                                Time for renumbering the final mesh: 0.0959 s

                                    Number of cells: 5820
                                    Minimum ref. level: 6
                                    Maximum ref. level: 12
                                    Captured metric of original grid: 50.13 %

[2025-08-15 14:31:37] INFO     Starting interpolation and export of field U.
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.
[2025-08-15 14:31:37] INFO     Writing HDF5 file for field U.
[2025-08-15 14:31:37] INFO     Writing XDMF file for file cylinder2D_deltaLevel_constraint.h5
[2025-08-15 14:31:37] INFO     Finished export of field U in 0.102s.

As already discussed in the introduction, we can see that the number of cells increased from \(4370\) to \(5820\) 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:

grid_noDeltaLevel_constraint.png

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:

grid_noDeltaLevel_constraint_zoomed.png

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:

grid_withDeltaLevel_constraint.png

When we zoom in the same region as before we can see that the grid quality improved significantly:

grid_deltaLevel_constraint_zoomed.png

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)
export.write_times = "10"
export.export(coord, field[:, :, -1].unsqueeze(-1), "U")
[2025-08-15 14:31:37] INFO
        Selected settings:
                _pre_select          :  False
                _n_jobs              :  4
                _max_delta_level     :  False
                _geometry            :  ['domain', 'cylinder']
                _min_metric          :  0.5
                _n_cells_max         :  None
                _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
[2025-08-15 14:31:37] INFO     Starting refinement:
        Starting iteration no. 0, N_cells = 1
        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 = 256
        Starting iteration no. 6, N_cells = 894
[2025-08-15 14:31:43] INFO     Finished uniform refinement.
[2025-08-15 14:31:43] INFO     Starting adaptive refinement.
        Starting iteration no. 0, captured metric: 55.05 %, N_cells = 3311
[2025-08-15 14:31:43] INFO     Finished adaptive refinement.
[2025-08-15 14:31:43] INFO     Starting geometry refinement.
[2025-08-15 14:31:43] INFO     Starting refining geometry cylinder.
[2025-08-15 14:31:44] INFO     Finished geometry refinement.
[2025-08-15 14:31:44] INFO     Starting renumbering final mesh.
[2025-08-15 14:31:44] INFO     Finished refinement in 7.0607 s
                                                                (1 iterations).
                                                                Time for uniform refinement: 5.9926 s
                                                                Time for adaptive refinement: 0.0530 s
                                                                Time for geometry refinement: 0.9304 s
                                                                Time for renumbering the final mesh: 0.0652 s

                                    Number of cells: 4807
                                    Minimum ref. level: 7
                                    Maximum ref. level: 12
                                    Captured metric of original grid: 55.41 %

[2025-08-15 14:31:44] INFO     Starting interpolation and export of field U.
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.
[2025-08-15 14:31:44] INFO     Writing HDF5 file for field U.
[2025-08-15 14:31:44] INFO     Writing XDMF file for file cylinder2D_6_uniform_levels.h5
[2025-08-15 14:31:44] INFO     Finished export of field U in 0.101s.

As we expected, the resulting grid is much more uniform than the grid using the default value of uniform_levels=5:

grid_7uniformLevels.png

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.

[ ]: