gitronics 0.5.3__tar.gz → 0.5.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. gitronics-0.5.5/.github/workflows/docs.yml +46 -0
  2. {gitronics-0.5.3 → gitronics-0.5.5}/.gitignore +1 -0
  3. {gitronics-0.5.3 → gitronics-0.5.5}/Cargo.lock +1 -1
  4. {gitronics-0.5.3 → gitronics-0.5.5}/Cargo.toml +2 -1
  5. {gitronics-0.5.3 → gitronics-0.5.5}/PKG-INFO +1 -1
  6. gitronics-0.5.5/README.md +103 -0
  7. gitronics-0.5.5/docs/best-practices.md +99 -0
  8. gitronics-0.5.5/docs/changelog.md +25 -0
  9. gitronics-0.5.5/docs/examples.md +110 -0
  10. gitronics-0.5.5/docs/getting-started.md +105 -0
  11. gitronics-0.5.5/docs/index.md +45 -0
  12. gitronics-0.5.5/docs/installation.md +54 -0
  13. gitronics-0.5.5/docs/requirements.txt +3 -0
  14. gitronics-0.5.5/docs/usage/build.md +52 -0
  15. gitronics-0.5.5/docs/usage/configuration.md +162 -0
  16. gitronics-0.5.5/docs/usage/migrate.md +63 -0
  17. gitronics-0.5.5/mkdocs.yml +77 -0
  18. gitronics-0.5.5/python/gitronics/__main__.py +3 -0
  19. {gitronics-0.5.3 → gitronics-0.5.5}/src/build_model.rs +28 -16
  20. {gitronics-0.5.3 → gitronics-0.5.5}/src/types.rs +0 -9
  21. {gitronics-0.5.3 → gitronics-0.5.5}/.github/workflows/ci.yml +0 -0
  22. {gitronics-0.5.3 → gitronics-0.5.5}/.github/workflows/release.yml +0 -0
  23. {gitronics-0.5.3 → gitronics-0.5.5}/LICENSE +0 -0
  24. {gitronics-0.5.3 → gitronics-0.5.5}/docs/logo.png +0 -0
  25. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/assessment_specific/filler_model_3.mcnp +0 -0
  26. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/assessment_specific/filler_model_3.metadata +0 -0
  27. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/assessment_specific/small_override.yaml +0 -0
  28. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/configurations/valid_configuration.yaml +0 -0
  29. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/output/.gitignore +0 -0
  30. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/data_cards/fine_mesh.tally +0 -0
  31. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/data_cards/materials.mat +0 -0
  32. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/data_cards/my_transform.transform +0 -0
  33. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/data_cards/volumetric_source.source +0 -0
  34. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/envelope_structure.mcnp +0 -0
  35. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/envelope_structure.metadata +0 -0
  36. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/filler_models/filler_model_1.mcnp +0 -0
  37. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/filler_models/filler_model_1.metadata +0 -0
  38. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/filler_models/filler_model_2.mcnp +0 -0
  39. {gitronics-0.5.3 → gitronics-0.5.5}/example_project/reference_model/filler_models/filler_model_2.metadata +0 -0
  40. {gitronics-0.5.3 → gitronics-0.5.5}/pyproject.toml +0 -0
  41. {gitronics-0.5.3 → gitronics-0.5.5}/python/gitronics/__init__.py +0 -0
  42. {gitronics-0.5.3 → gitronics-0.5.5}/python/tests/test_cli_works.py +0 -0
  43. {gitronics-0.5.3 → gitronics-0.5.5}/resources/simple_model.mcnp +0 -0
  44. {gitronics-0.5.3 → gitronics-0.5.5}/src/cli.rs +0 -0
  45. {gitronics-0.5.3 → gitronics-0.5.5}/src/lib.rs +0 -0
  46. {gitronics-0.5.3 → gitronics-0.5.5}/src/main.rs +0 -0
  47. {gitronics-0.5.3 → gitronics-0.5.5}/src/migrate_model.rs +0 -0
  48. {gitronics-0.5.3 → gitronics-0.5.5}/src/model_config.rs +0 -0
  49. {gitronics-0.5.3 → gitronics-0.5.5}/src/project_manager/load_metadata.rs +0 -0
  50. {gitronics-0.5.3 → gitronics-0.5.5}/src/project_manager/load_model_config.rs +0 -0
  51. {gitronics-0.5.3 → gitronics-0.5.5}/src/project_manager/load_project_files.rs +0 -0
  52. {gitronics-0.5.3 → gitronics-0.5.5}/src/project_manager.rs +0 -0
  53. {gitronics-0.5.3 → gitronics-0.5.5}/src/python.rs +0 -0
  54. {gitronics-0.5.3 → gitronics-0.5.5}/src/utils.rs +0 -0
  55. {gitronics-0.5.3 → gitronics-0.5.5}/tests/test_example_project.rs +0 -0
@@ -0,0 +1,46 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v[0-9]+.[0-9]+.[0-9]*"
7
+ # Allow manual triggering from the Actions tab
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: write # needed to push to gh-pages branch
12
+
13
+ jobs:
14
+ deploy-docs:
15
+ name: Build & deploy documentation
16
+ runs-on: ubuntu-latest
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ with:
21
+ # Fetch full history so mike can read previous deployments
22
+ fetch-depth: 0
23
+
24
+ - name: Set up Python
25
+ uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.11"
28
+
29
+ - name: Install documentation dependencies
30
+ run: pip install -r docs/requirements.txt
31
+
32
+ - name: Extract version from tag
33
+ id: version
34
+ run: |
35
+ # Strip the leading "v" so MkDocs sees "1.2.3", not "v1.2.3"
36
+ VERSION="${GITHUB_REF_NAME#v}"
37
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
38
+
39
+ - name: Build & deploy to GitHub Pages
40
+ run: |
41
+ git config user.name "github-actions[bot]"
42
+ git config user.email "github-actions[bot]@users.noreply.github.com"
43
+ # Deploy this version and update the "latest" alias
44
+ pip install mike
45
+ mike deploy --push --update-aliases "${{ steps.version.outputs.version }}" latest
46
+ mike set-default --push latest
@@ -4,3 +4,4 @@ __pycache__/
4
4
  *.so
5
5
  *.pyd
6
6
  *.pdb
7
+ /site
@@ -384,7 +384,7 @@ dependencies = [
384
384
 
385
385
  [[package]]
386
386
  name = "gitronics"
387
- version = "0.5.3"
387
+ version = "0.5.5"
388
388
  dependencies = [
389
389
  "chrono",
390
390
  "clap",
@@ -1,9 +1,10 @@
1
1
  [package]
2
2
  name = "gitronics"
3
- version = "0.5.3"
3
+ version = "0.5.5"
4
4
  edition = "2024"
5
5
  description = "Build MCNP neutronics models from modular components"
6
6
  license = "EUPL-1.2"
7
+ readme = "README.md"
7
8
 
8
9
  [[bin]]
9
10
  name = "gitronics"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitronics
3
- Version: 0.5.3
3
+ Version: 0.5.5
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -0,0 +1,103 @@
1
+ <div align="center">
2
+ <img src="docs/logo.png" alt="Gitronics logo" width="140"/>
3
+ <h1>Gitronics</h1>
4
+ <p><strong>Build MCNP neutronics models from modular, version-controlled components.</strong></p>
5
+
6
+ [![CI](https://github.com/Fusion4Energy/gitronics/actions/workflows/ci.yml/badge.svg)](https://github.com/Fusion4Energy/gitronics/actions/workflows/ci.yml)
7
+ [![Docs](https://github.com/Fusion4Energy/gitronics/actions/workflows/docs.yml/badge.svg)](https://fusion4energy.github.io/gitronics/latest/)
8
+ [![PyPI](https://img.shields.io/pypi/v/gitronics)](https://pypi.org/project/gitronics/)
9
+ [![License: EUPL-1.2](https://img.shields.io/badge/License-EUPL--1.2-blue.svg)](LICENSE)
10
+ </div>
11
+
12
+ ---
13
+
14
+ Gitronics lets you decompose a monolithic **MCNP** input file into independent, version-controllable components — universe filler models, an envelope structure, and separate data cards — and reassemble them at build time via a YAML configuration.
15
+
16
+ **Full documentation: [fusion4energy.github.io/gitronics](https://fusion4energy.github.io/gitronics/latest/)**
17
+
18
+ ## Why?
19
+
20
+ | Problem with monolithic models | Gitronics solution |
21
+ |---|---|
22
+ | `git diff` is unreadable | Each component is a separate file |
23
+ | Running variants means copying the whole file | Override only the fields that change |
24
+ | Teams can't work on sub-models in parallel | Each filler model is independent |
25
+ | Hard to know exactly what was run | Commit hash and timestamp written into every assembled file |
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install gitronics
31
+ ```
32
+
33
+ Requires Python 3.9+. Pre-built wheels for Linux, macOS, and Windows are published to PyPI — no Rust toolchain needed.
34
+
35
+ ## Quick start
36
+
37
+ **Migrate an existing model:**
38
+
39
+ ```bash
40
+ gitronics migrate path/to/my_model.mcnp --output-path ./my_project
41
+ ```
42
+
43
+ **Build a model:**
44
+
45
+ ```bash
46
+ gitronics build my_project/configurations/baseline.yaml --output-path my_project/output/
47
+ ```
48
+
49
+ **Get help:**
50
+
51
+ ```bash
52
+ gitronics --help
53
+ gitronics build --help
54
+ gitronics migrate --help
55
+ ```
56
+
57
+ ## Project layout
58
+
59
+ ```
60
+ my_project/
61
+ ├── configurations/
62
+ │ ├── baseline.yaml ← declares which fillers go where
63
+ │ └── variant_A.yaml ← inherits baseline, overrides selected envelopes
64
+ ├── output/
65
+ │ └── .gitignore
66
+ └── reference_model/
67
+ ├── envelope_structure.mcnp
68
+ ├── filler_models/
69
+ │ ├── component_A.mcnp
70
+ │ └── component_B.mcnp
71
+ └── data_cards/
72
+ ├── materials/
73
+ ├── sources/
74
+ └── tallies/
75
+ ```
76
+
77
+ ## Configuration example
78
+
79
+ ```yaml
80
+ project_roots: [..]
81
+
82
+ envelope_structure: envelope_structure
83
+ source: dt_plasma
84
+ materials: [all_materials]
85
+ tallies: [tritium_breeding_ratio]
86
+
87
+ envelopes:
88
+ blanket_inner: blanket_v3
89
+ blanket_outer: blanket_reference
90
+ divertor: null # void — no FILL card inserted
91
+ ```
92
+
93
+ Configurations support inheritance: a variant config can set `overrides: baseline.yaml` and override only the fields that differ.
94
+
95
+ ## Documentation
96
+
97
+ The full documentation covers installation, CLI reference, configuration options, best practices, and worked examples:
98
+
99
+ **[fusion4energy.github.io/gitronics](https://fusion4energy.github.io/gitronics/latest/)**
100
+
101
+ ## License
102
+
103
+ [EUPL-1.2](LICENSE)
@@ -0,0 +1,99 @@
1
+ # Best Practices
2
+
3
+ ## Project layout
4
+
5
+ ### Keep one project per repository
6
+
7
+ Each Gitronics project should live in its own repository (or a well-isolated subdirectory in a mono-repo). This makes branch history, tagging, and code review meaningful.
8
+
9
+ ### Use `.gitignore` in `output/`
10
+
11
+ The `migrate` command creates an `output/.gitignore` that ignores all files in that directory. Never commit assembled MCNP files — they are build artefacts and can be reproduced from the sources.
12
+
13
+ ### Prefer shallow directory trees for `project_roots`
14
+
15
+ Deeply nested source trees slow down file discovery. Keep filler models, data cards, and the envelope structure in predictable directories at one or two levels deep.
16
+
17
+ ---
18
+
19
+ ## Naming conventions
20
+
21
+ ### Use descriptive, lowercase stem names
22
+
23
+ Stem names appear in configuration files and in assembled-model metadata. Choose names that describe the *physics content*, not the version or date:
24
+
25
+ | Avoid | Prefer |
26
+ |---|---|
27
+ | `model_2024_v3_final` | `blanket_tungsten_fw` |
28
+ | `mat_13` | `reduced_activation_ferritic_steel` |
29
+ | `tally1` | `tritium_breeding_ratio` |
30
+
31
+ ### Match envelope names to physical regions
32
+
33
+ Envelope names in the configuration file (`envelopes:` map) must match the placeholder comments written in the envelope structure file. Naming them after the physical component they represent makes configurations self-documenting.
34
+
35
+ ---
36
+
37
+ ## Configuration management
38
+
39
+ ### Use a baseline + override hierarchy
40
+
41
+ Define a `baseline.yaml` that represents the full reference model. Create separate configuration files for each assessment or variant that override only the fields that differ. This minimises duplication and makes it easy to see what changed between assessments.
42
+
43
+ ```
44
+ configurations/
45
+ ├── baseline.yaml ← full reference model
46
+ ├── void_check.yaml ← overrides: baseline; all envelopes → null
47
+ ├── sensitivity_study_A.yaml ← overrides: baseline; changes one filler
48
+ └── assessment_specific/
49
+ └── design_point_X.yaml ← multi-level override chain
50
+ ```
51
+
52
+ ### Pin `project_roots` carefully
53
+
54
+ `project_roots` is resolved relative to the configuration file. Using `[..]` (the parent directory of `configurations/`) is the conventional choice and keeps paths stable when the project is cloned to different machines.
55
+
56
+ ---
57
+
58
+ ## Filler model design
59
+
60
+ ### One universe per file
61
+
62
+ Each filler model file should contain exactly one universe. This keeps the granularity consistent and makes `git blame` and `git log` useful at the component level.
63
+
64
+ ### Record transformation intent in metadata
65
+
66
+ If a filler model is placed with a transformation (`TR` card), document that in the `.metadata` file so the relationship between filler geometry and its placement is explicit. Avoid hardcoding transformations inside the filler MCNP file itself.
67
+
68
+ ### Avoid cross-references between fillers
69
+
70
+ Filler models should be self-contained. Cells in one filler should not reference surfaces or materials defined in another filler. Use the envelope structure for any shared bounding surfaces.
71
+
72
+ ---
73
+
74
+ ## Reproducibility
75
+
76
+ ### Tag releases
77
+
78
+ Every time you build a model for a formal assessment or publication, create a git tag. Gitronics records the commit hash in the assembled file's metadata, but a tag makes it trivially easy to check out the exact source state later.
79
+
80
+ ```bash
81
+ git tag -a v1.2.0 -m "Design freeze for TDR submission"
82
+ git push origin v1.2.0
83
+ ```
84
+
85
+ ### Include metadata files in version control
86
+
87
+ The `.metadata` files alongside each filler model are part of the source. Commit them alongside the `.mcnp` files.
88
+
89
+ ---
90
+
91
+ ## Performance
92
+
93
+ ### Use `RUST_LOG=info` during development
94
+
95
+ The `info` log level prints the files being loaded and the transformations being applied without being too verbose. Use `debug` only when diagnosing unexpected behaviour.
96
+
97
+ ### Keep filler models small
98
+
99
+ Very large filler models (tens of thousands of cells) slow down parsing. If a sub-model has grown large, consider whether it can be further decomposed into nested universes.
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ All notable changes to Gitronics are documented here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ---
8
+
9
+ <!-- TODO: Keep this file updated with each release. -->
10
+
11
+ ## [Unreleased]
12
+
13
+ ---
14
+
15
+ ## [0.1.0] — initial release
16
+
17
+ ### Added
18
+
19
+ - `build` command: assemble an MCNP model from modular components and a YAML configuration.
20
+ - `migrate` command: decompose a monolithic MCNP input file into a Gitronics project structure.
21
+ - Configuration inheritance via the `overrides` key.
22
+ - Multi-root project support via `project_roots`.
23
+ - Per-envelope void override (set filler to `null`).
24
+ - Python package (`pip install gitronics`) with `gitronics` CLI entry-point.
25
+ - Assembled model metadata header (version, git commit hash, build timestamp).
@@ -0,0 +1,110 @@
1
+ # Examples
2
+
3
+ ## `example_project` — minimal working project
4
+
5
+ The repository ships with a small example project in `example_project/`. It demonstrates the essential project layout and a valid configuration file.
6
+
7
+ ### Structure
8
+
9
+ ```
10
+ example_project/
11
+ ├── configurations/
12
+ │ └── valid_configuration.yaml
13
+ ├── output/
14
+ │ └── .gitignore
15
+ └── reference_model/
16
+ ├── envelope_structure.mcnp
17
+ ├── envelope_structure.metadata
18
+ └── filler_models/
19
+ ├── filler_model_1.mcnp
20
+ ├── filler_model_1.metadata
21
+ └── filler_model_2.mcnp
22
+ ```
23
+
24
+ ### Configuration
25
+
26
+ ```yaml title="example_project/configurations/valid_configuration.yaml"
27
+ project_roots: [..]
28
+
29
+ envelope_structure: envelope_structure
30
+
31
+ source: volumetric_source
32
+ materials: [materials]
33
+ transformations: [my_transform]
34
+ tallies: [fine_mesh]
35
+
36
+ envelopes:
37
+ my_envelope_name_1: filler_model_1
38
+ envelope_name_2: filler_model_2
39
+ ```
40
+
41
+ ### Building it
42
+
43
+ ```bash
44
+ cd example_project
45
+ gitronics build configurations/valid_configuration.yaml --output-path output/
46
+ ```
47
+
48
+ ---
49
+
50
+ ## `big_example` — large-scale fusion model
51
+
52
+ The `big_example/` directory contains a real-world-scale configuration for a tokamak neutronics model, showcasing how Gitronics handles large numbers of envelopes and multiple configuration variants.
53
+
54
+ ### Configuration variants
55
+
56
+ | File | Description |
57
+ |---|---|
58
+ | `baseline.yaml` | Full reference model with all blanket sectors and fillers. |
59
+ | `baseline_void_check.yaml` | Same geometry, all fillers replaced with void — useful for checking cell volumes. |
60
+ | `in_vessel_only.yaml` | Only the in-vessel components; useful for fast scoping calculations. |
61
+
62
+ ### Envelope / filler pattern
63
+
64
+ The baseline configuration maps blanket sectors to their corresponding filler models row by row:
65
+
66
+ ```yaml
67
+ envelopes:
68
+ blanket_sector_01_r1_c03: blk_dt1_w_fd_row_1_c03
69
+ blanket_sector_01_r1_c02: blk_dt1_w_fd_row_1_c02
70
+ blanket_sector_01_r1_c01: blk_dt1_w_fd_row_1_c01
71
+ # ...
72
+ ```
73
+
74
+ The `baseline_void_check.yaml` uses `overrides: baseline.yaml` and sets all envelopes to `null`, leaving the geometry intact but removing all materials — a standard MCNP void-check technique.
75
+
76
+ ### Running a build
77
+
78
+ ```bash
79
+ cd big_example
80
+ gitronics build configurations/baseline.yaml --output-path output/
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Migrating your own model
86
+
87
+ <!-- TODO: Add a worked example using a publicly available MCNP benchmark model -->
88
+
89
+ !!! note "Fill in this section"
90
+ If you have a representative public MCNP model you can share, add a migration walkthrough here showing:
91
+
92
+ 1. The original monolithic input file
93
+ 2. The `gitronics migrate` command
94
+ 3. The resulting project structure
95
+ 4. Any manual clean-up steps needed
96
+
97
+ ---
98
+
99
+ ## Using the Python API
100
+
101
+ Gitronics can also be driven from Python, which is useful when integrating with automated workflows or parametric studies:
102
+
103
+ ```python
104
+ import gitronics
105
+
106
+ # Build a model — equivalent to running the CLI
107
+ gitronics.run(["gitronics", "build", "configurations/baseline.yaml", "-o", "output/"])
108
+ ```
109
+
110
+ <!-- TODO: Expand with richer Python workflow examples if the Python API grows -->
@@ -0,0 +1,105 @@
1
+ # Getting Started
2
+
3
+ This page walks you through two typical entry points:
4
+
5
+ 1. **Starting fresh** — migrating an existing monolithic MCNP model into a Gitronics project.
6
+ 2. **Building** — assembling a model from an existing Gitronics project.
7
+
8
+ ---
9
+
10
+ ## Migrating an existing model
11
+
12
+ If you already have a monolithic MCNP input file, use the `migrate` command to convert it into a Gitronics project structure automatically.
13
+
14
+ ```bash
15
+ gitronics migrate path/to/my_model.mcnp --output-path ./my_project
16
+ ```
17
+
18
+ This produces:
19
+
20
+ ```
21
+ my_project/
22
+ ├── configurations/
23
+ │ └── baseline.yaml ← ready-to-use baseline configuration
24
+ ├── output/
25
+ │ └── .gitignore
26
+ └── reference_model/
27
+ ├── envelope_structure.mcnp
28
+ ├── envelope_structure.metadata
29
+ └── filler_models/
30
+ ├── universe_101.mcnp
31
+ ├── universe_101.metadata
32
+ └── ...
33
+ ```
34
+
35
+ !!! tip
36
+ The `migrate` command does its best to identify universe boundaries automatically.
37
+ Review the generated `envelope_structure.mcnp` and filler models to confirm they look correct before committing.
38
+
39
+ After migration, verify the round-trip by running a build:
40
+
41
+ ```bash
42
+ gitronics build my_project/configurations/baseline.yaml --output-path my_project/output
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Building a model
48
+
49
+ Given a Gitronics project, the `build` command assembles the MCNP input file:
50
+
51
+ ```bash
52
+ gitronics build configurations/baseline.yaml
53
+ ```
54
+
55
+ By default the assembled file is written to the current directory. Use `--output-path` to redirect it:
56
+
57
+ ```bash
58
+ gitronics build configurations/baseline.yaml --output-path output/
59
+ ```
60
+
61
+ The output file is `assembled.mcnp` in the specified directory.
62
+
63
+ ### What happens during a build
64
+
65
+ 1. The configuration file (and any parent configs it inherits from) is loaded and merged.
66
+ 2. All referenced files are located under the configured `project_roots`.
67
+ 3. `FILL` cards are injected into the envelope cells to reference the correct universe IDs.
68
+ 4. Filler models are appended to the envelope structure.
69
+ 5. Data cards (materials, source, tallies, transformations) are concatenated.
70
+ 6. A metadata comment block is written to the top of the output file recording the configuration name, build date, gitronics version, and git commit hash.
71
+
72
+ ---
73
+
74
+ ## Initialising a project from scratch
75
+
76
+ If you are starting a new model rather than migrating an existing one, create the directory layout manually:
77
+
78
+ ```
79
+ my_project/
80
+ ├── configurations/
81
+ │ └── baseline.yaml
82
+ ├── output/
83
+ │ └── .gitignore (contents: *)
84
+ └── reference_model/
85
+ ├── envelope_structure.mcnp
86
+ ├── envelope_structure.metadata
87
+ ├── filler_models/
88
+ └── data_cards/
89
+ ├── materials/
90
+ ├── sources/
91
+ └── tallies/
92
+ ```
93
+
94
+ Then write a minimal `baseline.yaml`:
95
+
96
+ ```yaml
97
+ project_roots: [..]
98
+
99
+ envelope_structure: envelope_structure
100
+
101
+ envelopes:
102
+ my_envelope: my_filler_model
103
+ ```
104
+
105
+ See the [Configuration Reference](usage/configuration.md) for all available keys.
@@ -0,0 +1,45 @@
1
+ # Gitronics
2
+
3
+ **Gitronics** is a tool for assembling [MCNP](https://mcnp.lanl.gov/) neutronics models from modular, version-controlled components.
4
+
5
+ Instead of maintaining a single monolithic MCNP input file, Gitronics lets you decompose a model into independent universe *filler models*, an *envelope structure*, and separate data cards (materials, sources, tallies, transformations). These components are assembled at build time according to a YAML configuration file.
6
+
7
+ This workflow enables:
8
+
9
+ - **Version control** — each component lives in its own file, making `git diff` meaningful.
10
+ - **Parametric variants** — swap geometry fillers or data cards via configuration inheritance without duplicating files.
11
+ - **Parallelism** — teams can develop different sub-models independently.
12
+ - **Reproducibility** — each assembled model records the git commit hash and build timestamp in its metadata.
13
+
14
+ ---
15
+
16
+ ## How it works
17
+
18
+ ```
19
+ reference_model/
20
+ ├── envelope_structure.mcnp ← level-0 cells (the "shell" of the model)
21
+ ├── filler_models/ ← per-universe MCNP snippets
22
+ │ ├── universe_101.mcnp
23
+ │ └── ...
24
+ └── data_cards/
25
+ ├── materials/
26
+ ├── sources/
27
+ └── tallies/
28
+
29
+ configurations/
30
+ └── baseline.yaml ← declares which fillers go where
31
+
32
+ output/
33
+ └── assembled.mcnp ← produced by `gitronics build`
34
+ ```
35
+
36
+ The `build` command reads a configuration file, loads all referenced components, inserts `FILL` cards into the envelope cells, and writes a single self-contained MCNP input file.
37
+
38
+ ---
39
+
40
+ ## Quick links
41
+
42
+ - [Installation](installation.md)
43
+ - [Getting Started](getting-started.md)
44
+ - [Configuration Reference](usage/configuration.md)
45
+ - [Examples](examples.md)
@@ -0,0 +1,54 @@
1
+ # Installation
2
+
3
+ Gitronics is distributed as a Python package containing a compiled Rust extension. Pre-built wheels are published to [PyPI](https://pypi.org/project/gitronics/) for the most common platforms; no Rust toolchain is required for end users.
4
+
5
+ ## Requirements
6
+
7
+ - Python **3.9** or later
8
+ - A supported platform: Linux x86\_64 / aarch64, macOS x86\_64 / Apple Silicon, Windows x86\_64
9
+
10
+ ## Install from PyPI
11
+
12
+ ```bash
13
+ pip install gitronics
14
+ ```
15
+
16
+ After installation the `gitronics` command is available in your shell:
17
+
18
+ ```bash
19
+ gitronics --help
20
+ ```
21
+
22
+ ## Install from source
23
+
24
+ Building from source requires:
25
+
26
+ - [Rust](https://rustup.rs/) (stable toolchain)
27
+ - [maturin](https://github.com/PyO3/maturin) ≥ 1.0
28
+
29
+ ```bash
30
+ git clone https://github.com/gitronics/gitronics # TODO: update URL
31
+ cd gitronics
32
+ pip install maturin
33
+ maturin develop --release
34
+ ```
35
+
36
+ ## Verifying the installation
37
+
38
+ ```bash
39
+ gitronics --help
40
+ # Usage: gitronics <COMMAND>
41
+ # Commands:
42
+ # build Build an MCNP model from a project configuration
43
+ # migrate Take a traditional monolithic MCNP model and migrate it to a Gitronics project structure
44
+ # help Print this message or the help of the given subcommand(s)
45
+ ```
46
+
47
+ ## Building the documentation locally
48
+
49
+ ```bash
50
+ pip install -r docs/requirements.txt
51
+ mkdocs serve
52
+ ```
53
+
54
+ Open [http://127.0.0.1:8000](http://127.0.0.1:8000) in your browser.
@@ -0,0 +1,3 @@
1
+ mkdocs-material
2
+ mkdocs-autorefs
3
+ mike
@@ -0,0 +1,52 @@
1
+ # `build` — Assemble a Model
2
+
3
+ The `build` command reads a YAML configuration file and assembles a ready-to-run MCNP input file.
4
+
5
+ ## Synopsis
6
+
7
+ ```
8
+ gitronics build <CONFIG> [--output-path <DIR>]
9
+ ```
10
+
11
+ | Argument | Description |
12
+ |---|---|
13
+ | `CONFIG` | Path to the configuration YAML file (absolute or relative to cwd). |
14
+ | `-o`, `--output-path` | Directory to write `assembled.mcnp` into. Defaults to `.` (current directory). |
15
+
16
+ ## Example
17
+
18
+ ```bash
19
+ gitronics build configurations/in_vessel_only.yaml --output-path output/
20
+ ```
21
+
22
+ ## Output
23
+
24
+ On success, the following files are written to `--output-path`:
25
+
26
+ | File | Description |
27
+ |---|---|
28
+ | `assembled.mcnp` | The complete, self-contained MCNP input deck. |
29
+
30
+ The top of `assembled.mcnp` contains a metadata comment block:
31
+
32
+ ```
33
+ C ============================================================
34
+ C Built by gitronics v0.1.0
35
+ C Configuration : configurations/in_vessel_only.yaml
36
+ C Git commit : a1b2c3d4e5f6...
37
+ C Date / time : 2025-01-15T14:32:00Z
38
+ C ============================================================
39
+ ```
40
+
41
+ ## How files are located
42
+
43
+ Gitronics searches all directories listed in `project_roots` (defined in the configuration) for files referenced by stem name. Any file whose stem (name without extension) matches a key in the configuration is a candidate. This means you can organise your project files into subdirectories however you like, as long as each stem name is unique across all `project_roots`.
44
+
45
+ ## Logging
46
+
47
+ Set the `RUST_LOG` environment variable to control verbosity:
48
+
49
+ ```bash
50
+ RUST_LOG=info gitronics build configurations/baseline.yaml
51
+ RUST_LOG=debug gitronics build configurations/baseline.yaml
52
+ ```
@@ -0,0 +1,162 @@
1
+ # Configuration Reference
2
+
3
+ Gitronics configurations are YAML files that declare which components to include in an assembled model.
4
+
5
+ ## Full example
6
+
7
+ ```yaml
8
+ # Where to search for referenced files (relative to this config file's directory)
9
+ project_roots: [..]
10
+
11
+ # Inherit from a parent config and override selected fields
12
+ overrides: null
13
+
14
+ # File stem of the envelope structure MCNP file
15
+ envelope_structure: envelope_structure
16
+
17
+ # Data card files (stems) to include
18
+ source: volumetric_source
19
+ materials: [materials_v2, extra_nuclides]
20
+ transformations: [sector_transforms]
21
+ tallies: [fine_mesh_tally, heating_tally]
22
+
23
+ # Maps envelope cell names to filler model stems
24
+ # Set a value to null to leave that envelope void (no FILL card inserted)
25
+ envelopes:
26
+ blanket_sector_01: blanket_v3
27
+ divertor_outer: divertor_cassette
28
+ shielding_block: null
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Field reference
34
+
35
+ ### `project_roots`
36
+
37
+ ```yaml
38
+ project_roots: [.., ../shared_models]
39
+ ```
40
+
41
+ A list of directory paths (relative to the config file or absolute) that Gitronics searches recursively for referenced files. Paths are resolved at load time.
42
+
43
+ - **Type:** `list[path]` or `null`
44
+ - **Default:** `null` (must be provided by the base config in an inheritance chain)
45
+
46
+ ---
47
+
48
+ ### `overrides`
49
+
50
+ ```yaml
51
+ overrides: ../configurations/baseline.yaml
52
+ ```
53
+
54
+ Path to a *parent* configuration. If set, the parent is loaded first and the current file is merged on top of it. Fields present in the current file take precedence; the parent provides defaults.
55
+
56
+ - **Type:** `path` or `null`
57
+ - **Default:** `null` (standalone config)
58
+
59
+ !!! info "Inheritance"
60
+ Inheritance chains can be arbitrarily deep. The `envelopes` map is merged entry-by-entry: the override can add new envelopes or change specific ones without repeating the full list.
61
+
62
+ ---
63
+
64
+ ### `envelope_structure`
65
+
66
+ ```yaml
67
+ envelope_structure: envelope_structure
68
+ ```
69
+
70
+ Stem name of the MCNP file that contains the level-0 cells. Each cell that should be filled with a filler universe must have a placeholder comment `C @<envelope_name>` on the line before it (inserted automatically by `migrate`).
71
+
72
+ - **Type:** `string` or `null`
73
+
74
+ ---
75
+
76
+ ### `source`
77
+
78
+ ```yaml
79
+ source: volumetric_plasma_dt
80
+ ```
81
+
82
+ Stem name of the file containing the SDEF / source data card.
83
+
84
+ - **Type:** `string` or `null`
85
+
86
+ ---
87
+
88
+ ### `materials`
89
+
90
+ ```yaml
91
+ materials: [structural_materials, tritium_breeding_materials]
92
+ ```
93
+
94
+ List of stem names for material definition files. Files are concatenated in the listed order.
95
+
96
+ - **Type:** `list[string]` or `null`
97
+
98
+ ---
99
+
100
+ ### `transformations`
101
+
102
+ ```yaml
103
+ transformations: [sector_transforms, assembly_transforms]
104
+ ```
105
+
106
+ List of stem names for transformation card files (`TR` cards). Files are concatenated in the listed order.
107
+
108
+ - **Type:** `list[string]` or `null`
109
+
110
+ ---
111
+
112
+ ### `tallies`
113
+
114
+ ```yaml
115
+ tallies: [flux_tally, heating_tally]
116
+ ```
117
+
118
+ List of stem names for tally card files. Files are concatenated in the listed order.
119
+
120
+ - **Type:** `list[string]` or `null`
121
+
122
+ ---
123
+
124
+ ### `envelopes`
125
+
126
+ ```yaml
127
+ envelopes:
128
+ blanket_sector_01: blanket_v3
129
+ divertor_outer: null
130
+ ```
131
+
132
+ A mapping from **envelope cell name** (as declared in the envelope structure file) to a **filler model stem name**. Setting a value to `null` leaves the envelope void — no `FILL` card is inserted for that cell.
133
+
134
+ - **Type:** `map[string, string | null]`
135
+ - **Default:** `{}` (empty map)
136
+
137
+ ---
138
+
139
+ ## Configuration inheritance example
140
+
141
+ A common pattern is to have a `baseline.yaml` that declares the full reference model, and assessment-specific configs that override only what changes:
142
+
143
+ ```yaml title="configurations/baseline.yaml"
144
+ project_roots: [..]
145
+ envelope_structure: envelope_structure
146
+ source: dt_plasma
147
+ materials: [all_materials]
148
+ tallies: []
149
+ envelopes:
150
+ blanket_inner: blanket_reference
151
+ blanket_outer: blanket_reference
152
+ divertor: divertor_reference
153
+ ```
154
+
155
+ ```yaml title="configurations/assessment_A.yaml"
156
+ overrides: baseline.yaml
157
+ tallies: [heating_mesh]
158
+ envelopes:
159
+ blanket_inner: blanket_variant_A
160
+ ```
161
+
162
+ When `assessment_A.yaml` is built, `blanket_inner` uses `blanket_variant_A` while `blanket_outer` and `divertor` fall back to the baseline values.
@@ -0,0 +1,63 @@
1
+ # `migrate` — Convert a Monolithic Model
2
+
3
+ The `migrate` command takes a traditional single-file MCNP input deck and decomposes it into a Gitronics project structure.
4
+
5
+ ## Synopsis
6
+
7
+ ```
8
+ gitronics migrate <MCNP_INPUT> [--output-path <DIR>]
9
+ ```
10
+
11
+ | Argument | Description |
12
+ |---|---|
13
+ | `MCNP_INPUT` | Path to the original monolithic MCNP input file. |
14
+ | `-o`, `--output-path` | Root directory for the new project. Defaults to `./project`. |
15
+
16
+ ## Example
17
+
18
+ ```bash
19
+ gitronics migrate models/tokamak_2025.mcnp --output-path ./tokamak_project
20
+ ```
21
+
22
+ ## What it produces
23
+
24
+ ```
25
+ <output-path>/
26
+ ├── configurations/
27
+ │ └── baseline.yaml ← reproduces the original model exactly
28
+ ├── output/
29
+ │ └── .gitignore ← ignores all build outputs in git
30
+ └── reference_model/
31
+ ├── envelope_structure.mcnp ← level-0 cells
32
+ ├── envelope_structure.metadata
33
+ └── filler_models/
34
+ ├── universe_<id>.mcnp ← one file per universe
35
+ ├── universe_<id>.metadata
36
+ └── ...
37
+ ```
38
+
39
+ ### How universes are extracted
40
+
41
+ Each universe found in the model is written to its own `universe_<id>.mcnp` file. Cells belonging to universe 0 (the root lattice) are retained in the envelope structure.
42
+
43
+ ### Metadata files
44
+
45
+ Each filler model is accompanied by a `.metadata` YAML file. These files describe how the filler should be placed and can specify per-envelope transformation cards. Edit them to add transformations after migration.
46
+
47
+ ## Verifying the round-trip
48
+
49
+ After migration, rebuild the model and verify it matches the original:
50
+
51
+ ```bash
52
+ gitronics build tokamak_project/configurations/baseline.yaml \
53
+ --output-path tokamak_project/output
54
+ diff models/tokamak_2025.mcnp tokamak_project/output/assembled.mcnp
55
+ ```
56
+
57
+ !!! note
58
+ Minor formatting differences (whitespace, line ordering within a section) are expected. The geometry and physics data should be functionally identical.
59
+
60
+ ## Limitations
61
+
62
+ - Data cards (materials, tallies, source) are written to a single `data_cards.source` file. After migration you may wish to split these into separate files under `reference_model/data_cards/`.
63
+ - The migration does not attempt to detect repeated structures or simplify the model.
@@ -0,0 +1,77 @@
1
+ site_name: Gitronics
2
+ site_description: Build MCNP neutronics models from modular components
3
+ site_url: https://fusion4energy.github.io/gitronics/latest/
4
+ repo_url: https://github.com/Fusion4Energy/gitronics
5
+ repo_name: Fusion4Energy/gitronics
6
+ edit_uri: edit/main/docs/
7
+
8
+ theme:
9
+ name: material
10
+ logo: logo.png
11
+ favicon: logo.png
12
+ palette:
13
+ - scheme: default
14
+ primary: deep purple
15
+ accent: teal
16
+ toggle:
17
+ icon: material/brightness-7
18
+ name: Switch to dark mode
19
+ - scheme: slate
20
+ primary: deep purple
21
+ accent: teal
22
+ toggle:
23
+ icon: material/brightness-4
24
+ name: Switch to light mode
25
+ features:
26
+ - navigation.tabs
27
+ - navigation.sections
28
+ - navigation.expand
29
+ - navigation.path
30
+ - navigation.top
31
+ - search.highlight
32
+ - search.share
33
+ - content.code.copy
34
+ - content.code.annotate
35
+ - content.tabs.link
36
+ - toc.integrate
37
+
38
+ plugins:
39
+ - search
40
+ - autorefs
41
+
42
+ extra:
43
+ version:
44
+ provider: mike
45
+ default: latest
46
+
47
+ markdown_extensions:
48
+ - admonition
49
+ - pymdownx.details
50
+ - pymdownx.superfences
51
+ - pymdownx.highlight:
52
+ anchor_linenums: true
53
+ line_spans: __span
54
+ pygments_lang_class: true
55
+ - pymdownx.inlinehilite
56
+ - pymdownx.tabbed:
57
+ alternate_style: true
58
+ - pymdownx.tasklist:
59
+ custom_checkbox: true
60
+ - attr_list
61
+ - md_in_html
62
+ - tables
63
+ - footnotes
64
+ - toc:
65
+ permalink: true
66
+
67
+ nav:
68
+ - Home: index.md
69
+ - Installation: installation.md
70
+ - Getting Started: getting-started.md
71
+ - Usage:
72
+ - Build: usage/build.md
73
+ - Migrate: usage/migrate.md
74
+ - Configuration Reference: usage/configuration.md
75
+ - Best Practices: best-practices.md
76
+ - Examples: examples.md
77
+ - Changelog: changelog.md
@@ -0,0 +1,3 @@
1
+ from gitronics import _cli_main
2
+
3
+ _cli_main()
@@ -1,10 +1,10 @@
1
1
  use crate::project_manager::ProjectManager;
2
- use crate::types::{AssembledMetadata, CellId, EnvelopeName, FillerName, UniverseId};
2
+ use crate::types::{CellId, EnvelopeName, FillerName, UniverseId};
3
3
  use crate::utils::GitronicsError;
4
4
 
5
5
  use git2::Repository;
6
6
  use log::{info, warn};
7
- use migjorn::{Card, CellParam, DataCard, Model, ParamType};
7
+ use migjorn::{Card, CellCard, CellParam, DataCard, Model, ParamType};
8
8
  use regex::Regex;
9
9
  use std::{collections::HashMap, path::Path, sync::LazyLock};
10
10
  use std::{env, fs};
@@ -63,8 +63,8 @@ pub fn build_model(config_path: &Path, output_path: &Path) -> Result<(), Gitroni
63
63
 
64
64
  // Write model
65
65
  let assembled_path = project_manager.output_path().join("assembled.mcnp");
66
+ write_assembled_header(&mut envelope_structure, config_path)?;
66
67
  envelope_structure.write_to_file(&assembled_path)?;
67
- write_assembled_metadata(&project_manager, config_path)?;
68
68
  fs::write(output_path.join(".gitignore"), "*\n")?;
69
69
 
70
70
  info!(
@@ -168,25 +168,37 @@ fn get_universe_id_of_model(model: &Model) -> Result<UniverseId, GitronicsError>
168
168
  .ok_or_else(|| GitronicsError::FirstCellWithoutUniverseID(FillerName::from(model)))
169
169
  }
170
170
 
171
- fn write_assembled_metadata(
172
- project_manager: &ProjectManager,
171
+ fn write_assembled_header(
172
+ assembled_model: &mut Model,
173
173
  config_path: &Path,
174
174
  ) -> Result<(), GitronicsError> {
175
175
  let configuration = config_path.display().to_string();
176
176
  let date_time = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S").to_string();
177
177
  let gitronics_version = env!("CARGO_PKG_VERSION");
178
178
  let commit_hash = get_hash_of_project();
179
- let assembled_metadata = AssembledMetadata {
180
- configuration,
181
- date_time,
182
- gitronics_version: gitronics_version.to_string(),
183
- git_commit_hash: commit_hash,
184
- };
185
- let metadata_path = project_manager.output_path().join("assembled.metadata");
186
- let yaml_content = serde_saphyr::to_string(&assembled_metadata).map_err(|e| {
187
- GitronicsError::YamlSerialize(metadata_path.display().to_string(), e.to_string())
188
- })?;
189
- fs::write(&metadata_path, yaml_content)?;
179
+
180
+ let banner = format!(
181
+ "C ============================================================
182
+ C Built by gitronics v{gitronics_version}
183
+ C Configuration : {configuration}
184
+ C Git commit : {commit_hash}
185
+ C Date / time : {date_time}
186
+ C ============================================================"
187
+ );
188
+ let new_card_text = format!(
189
+ "{banner}\n{}",
190
+ assembled_model
191
+ .cells
192
+ .first()
193
+ .map(|c| c.original_text())
194
+ .unwrap_or_default()
195
+ );
196
+
197
+ let banner_card = CellCard::try_from(new_card_text.as_str())
198
+ .expect("Adding comments as header should not fail");
199
+
200
+ // Replace the first cell (previously a comment placeholder) with the banner card
201
+ assembled_model.cells[0] = banner_card;
190
202
  Ok(())
191
203
  }
192
204
 
@@ -11,15 +11,6 @@ use indexmap::IndexMap;
11
11
  use migjorn::Model;
12
12
  use serde::{Deserialize, Serialize};
13
13
 
14
- /// Metadata associated with an assembled model
15
- #[derive(Debug, Serialize, Deserialize)]
16
- pub struct AssembledMetadata {
17
- pub configuration: String,
18
- pub date_time: String,
19
- pub gitronics_version: String,
20
- pub git_commit_hash: String,
21
- }
22
-
23
14
  /// Metadata associated with a filler model, describing how it should be placed.
24
15
  #[derive(Debug, Serialize, Deserialize)]
25
16
  pub struct FillerMetadata {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes