{"id":37625390,"url":"https://github.com/martenlienen/generative-turbulence","last_synced_at":"2026-01-16T10:47:07.298Z","repository":{"id":228158006,"uuid":"772039491","full_name":"martenlienen/generative-turbulence","owner":"martenlienen","description":"Generative turbulence model TurbDiff as proposed in \"From Zero to Turbulence: Generative Modeling for 3D Flow Simulation\", ICLR 2024","archived":false,"fork":false,"pushed_at":"2025-02-19T10:47:00.000Z","size":663,"stargazers_count":28,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-14T09:37:29.798Z","etag":null,"topics":["generative-ai","navier-stokes","simulation","turbulence"],"latest_commit_sha":null,"homepage":"https://cs.cit.tum.de/daml/generative-turbulence","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martenlienen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-03-14T12:24:26.000Z","updated_at":"2025-09-30T07:58:40.000Z","dependencies_parsed_at":"2024-04-30T10:39:39.290Z","dependency_job_id":"032af700-fa1c-4013-ab1c-56cac53b24fc","html_url":"https://github.com/martenlienen/generative-turbulence","commit_stats":null,"previous_names":["martenlienen/generative-turbulence"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/martenlienen/generative-turbulence","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martenlienen%2Fgenerative-turbulence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martenlienen%2Fgenerative-turbulence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martenlienen%2Fgenerative-turbulence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martenlienen%2Fgenerative-turbulence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martenlienen","download_url":"https://codeload.github.com/martenlienen/generative-turbulence/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martenlienen%2Fgenerative-turbulence/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28478058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["generative-ai","navier-stokes","simulation","turbulence"],"created_at":"2026-01-16T10:47:06.722Z","updated_at":"2026-01-16T10:47:07.285Z","avatar_url":"https://github.com/martenlienen.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# From Zero to Turbulence: Generative Modeling for 3D Flow Simulation\n\nMarten Lienen, David Lüdke, Jan Hansen-Palmus, Stephan Günnemann\n\n![](./figures/generated-sample-curl-norm.png)\n\nThis repository contains the code used to produce the results in our paper: [openreview](https://openreview.net/forum?id=ZhlwoC1XaN), [arxiv](https://arxiv.org/abs/2306.01776).\n\nBesides the model, data loading and training code, this repository also contains code to configure and run OpenFOAM and postprocess its outputs. These tools could be an immensely useful starting point for other researchers in the field. In particular, there is\n- a [lark](https://github.com/lark-parser/lark) [grammar for the OpenFOAM configuration format](./turbdiff/openfoam.lark),\n- a [python module](./turbdiff/openfoam.py) using this grammar to load, edit and save these configuration files,\n- a script to [generate new OpenFOAM cases](./scripts/les-case.py) from a template,\n- a script to [generate regular meshes with arbitrary axis-aligned shapes cut out](./scripts/channel-3d.py),\n- a script to [run simulations on a SLURM cluster](./scripts/solve-slurm.py) in a docker container via [udocker](https://github.com/indigo-dc/udocker),\n- a script to [convert OpenFOAM outputs into much more performant HDF5 files](./scripts/foam2h5.py),\n- and a script to [precompute an embedding of the sparse 3D data](./scripts/grid-embedding.py) into dense 3D tensors with padding layers to encode boundary information.\nOur [data loader](./turbdiff/data/ofles.py) lets you load all this information into easily digestible data classes. To get started right away, copy and paste the 20 line snippet of code [further below](#loading-the-dataset-for-your-own-project) that loads the data into easy-to-work-with matrices.\n\n## Installation\n\n```sh\n# Clone the repository\ngit clone https://github.com/martenlienen/generative-turbulence.git\n\n# Change into the repository\ncd generative-turbulence\n\n# Install package editably with dependencies\npip install -e .\n\n# If you need a specific pytorch version, e.g. CPU-only or an older CUDA version, check\n#\n#     https://pytorch.org/get-started/locally/\n#\n# and run, for example,\n#\n# pip install torch --extra-index-url https://download.pytorch.org/whl/cu117\n#\n# before installing this package.\n```\n\nAlternatively, you can use [pixi](https://pixi.sh) to quickly set up a working environment.\nAfter installing it with `curl -fsSL https://pixi.sh/install.sh | bash`, install and activate the environment at the same time with `pixi shell`.\n\n## Dataset\n\nThe shapes dataset is hosted at [TUM university library](https://mediatum.ub.tum.de/1737748). To download it, either follow the instructions on their page or execute the following steps. First, download the files.\n```sh\n# Download all archives to data/shapes/download\nscripts/download-dataset.sh\n```\nNote, that this can take a long time as the processed data is roughly 2TB. The script uses `rsync`, so you can resume partial downloads. If you also want to download the raw OpenFOAM case data, run instead\n```sh\nscripts/download-dataset.sh --with-raw\n```\nAfter downloading the invididual archives, you need to extract the files. The following script does so for you\n```sh\nscripts/extract-dataset.sh\n```\nAfterwards, you can start training the model as described below.\n\n### Loading the dataset for your own project\n\nThe following snippet loads data from any of the `data.h5` files in the dataset for you to explore and experiment with.\n\n```python\nimport numpy as np\nimport h5py as h5\n\ndef load_data(path, idx, features = [\"u\", \"p\"]):\n    \"\"\"Load data from a data.h5 file into an easily digestible matrix format.\n\n    Arguments\n    ---------\n    path\n        Path to a data.h5 file in the `shapes` dataset\n    idx\n        Index or indices of sample to load. Can be a number, list, boolean mask or a slice.\n    features\n        Features to load. By default loads only velocity and pressure but you can also\n        access the LES specific k and nut variables.\n\n    Returns\n    -------\n    t: np.ndarray of shape T\n        Time steps of the loaded data frames\n    data_3d: np.ndarray of shape T x W x H x D x F\n        3D data with all features concatenated in the order that they are requested, i.e.\n        in the default case the first 3 features will be the velocity vector and the fourth\n        will be the pressure\n    inside_mask: np.ndarray of shape W x H x D\n        Boolean mask that marks the inside cells of the domain, i.e. cells that are not part\n        of walls, inlets or outlets\n    boundary_masks: dict of str to nd.ndarray of shape W x H x D\n        Masks that mark cells belonging to each type of boundary\n    boundary_values: dict[str, dict[str, np.ndarray]]\n        Prescribed values for variables and boundaries with Dirichlet boundary conditions\n    \"\"\"\n\n    with h5.File(path, mode=\"r\") as f:\n        t = np.array(f[\"data/times\"])\n\n        cell_data = np.concatenate([np.atleast_3d(f[\"data\"][name][idx]) for name in features], axis=-1)\n        padded_cell_counts = np.array(f[\"grid/cell_counts\"])\n        cell_idx = np.array(f[\"grid/cell_idx\"])\n\n        n_steps, n_features = cell_data.shape[0], cell_data.shape[-1]\n        data_3d = np.zeros((n_steps, *padded_cell_counts, n_features))\n        data_3d.reshape((n_steps, -1, n_features))[:, cell_idx] = cell_data\n\n        inside_mask = np.zeros(padded_cell_counts, dtype=bool)\n        inside_mask.reshape(-1)[cell_idx] = 1\n\n        boundary_masks = {name: np.zeros(padded_cell_counts, dtype=bool) for name in f[\"grid/boundaries\"].keys()}\n        for name, mask in boundary_masks.items():\n            mask.reshape(-1)[np.array(f[\"grid/boundaries\"][name])] = 1\n\n        boundary_values = {\n            ft: {\n                name: np.atleast_1d(desc[\"value\"])\n                for name, desc in f[\"boundary-conditions\"][ft].items()\n                if desc.attrs[\"type\"] == \"fixed-value\"\n            }\n            for ft in features\n        }\n\n    return t, data_3d, inside_mask, boundary_masks, boundary_values\n```\n\nYou can use it like\n\n```python\nfrom matplotlib.pyplot import matshow\n\npath = \"data/shapes/data/2x2-large/data.h5\"\nt, data_3d, inside_mask, boundary_masks, boundary_values = load_data(path, [50, 300])\n\nmatshow(np.linalg.norm(data_3d[-1, :, :, 20, :3], axis=-1).T)\n```\n\n![](./figures/data-velocity-norm.png)\n\nThe `data.h5` files contain more information than this snippet loads. To explore what else is available, poke around in our [data loader](./turbdiff/data/ofles.py).\n\n### Data generation with OpenFOAM in docker\n\nTo generate data for new OpenFOAM simulations, first make sure that you have installed the extra dependencies and have [`just`](https://just.systems/) available:\n```sh\npip install -e \".[data]\"\n```\nIf you don't want to use `just`, you can also read the [`justfile`](./justfile) and run the commands yourself.\n\nBegin by creating a docker container with OpenFOAM installed:\n```sh\njust of-docker\n```\n\nNow generate a bunch of new cases. For example, the following sets up all the OpenFOAM cases (simulations) from our dataset:\n```sh\n./scripts/generate-shapes.py data/shapes\n```\nOf course, you can adapt the script to create other shapes or completely new datasets.\n\nNow you can solve the case (run the simulation) with OpenFOAM locally\n```sh\njust of-solve path/to/case\n```\nor submit a whole bunch of them to your own SLURM cluster:\n```sh\n./scripts/solve-slurm.py data/shapes/data/*/case\n```\n\nAfterwards, apply the postprocessing, e.g. the HDF5 conversion, to each simulation, for example\n```sh\njust postprocess data/shapes/data/2x2\n```\n\nFinally, compute the training set statistics for feature normalization:\n```sh\n./scripts/dataset-stats.py data/shapes\n```\n\n## Training\n\nTo start a training, call `train.py` with the your settings, for example\n```sh\n./train.py data.batch_size=128\n```\nThe training script uses [hydra](https://hydra.cc) for configuration, so check out the files in the `config` directory, to learn about all available settings.\n\nTo re-run the experiments from the paper, execute\n```sh\n./train.py -cn shapes_experiment -m\n```\nwhich starts training with the settings in [`config/shapes_experiment.yaml`](./config/shapes_experiment.yaml). If you don't have a SLURM cluster available, remove the settings related to `launcher`.\n\n## Pretrained Checkpoint\n\nYou can download a pretrained checkpoint from [zenodo](https://zenodo.org/records/14892192/files/turbdiff.ckpt) with `curl -O https://zenodo.org/records/14892192/files/turbdiff.ckpt`.\nTo generate samples from it or any of your own checkpoints, run\n```sh\nscripts/eval_ckpt.py turbdiff.ckpt samples.h5 data.batch_size=256\n```\nThe script lets you override any configuration values such as `data.batch_size` in the example above.\n`eval_ckpt.py` also serves as a great starting point for other types of evaluations.\n\n## Citation\n\nIf you build upon this work, please cite our paper as follows.\n\n```\n@inproceedings{lienen2024zero,\n  title = {From {{Zero}} to {{Turbulence}}: {{Generative Modeling}} for {{3D Flow Simulation}}},\n  author = {Lienen, Marten and L{\\\"u}dke, David and {Hansen-Palmus}, Jan and G{\\\"u}nnemann, Stephan},\n  booktitle = {International {{Conference}} on {{Learning Representations}}},\n  year = {2024},\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartenlienen%2Fgenerative-turbulence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartenlienen%2Fgenerative-turbulence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartenlienen%2Fgenerative-turbulence/lists"}