Skip to content

Commit 4853164

Browse files
committed
Rewrite README to focus on algorithm background and use cases
1 parent 555bd35 commit 4853164

1 file changed

Lines changed: 75 additions & 214 deletions

File tree

README.md

Lines changed: 75 additions & 214 deletions
Original file line numberDiff line numberDiff line change
@@ -1,260 +1,121 @@
1-
# VirMat: Virtual Microstructure Generator
1+
# VirMat
22

3-
**VirMat** is a high-performance 2D and 3D virtual microstructure generator written in Haskell, designed for metallurgical and materials science research. It creates synthetic polycrystalline microstructures with user-defined grain size distributions and crystallographic textures, producing output suitable for visualization in [ParaView](https://www.paraview.org/) and analysis with EBSD software.
3+
Virtual microstructure generator for 2D and 3D polycrystalline materials.
44

5-
## Core Features
5+
## What is this?
66

7-
- **2D and 3D generation** -- produce microstructures in either dimensionality from a single CLI.
8-
- **Statistical grain size control** -- specify Log-Normal, Normal, Uniform, or custom grain diameter distributions; combine multiple distributions for multi-modal populations.
9-
- **Sphere/circle packing** -- optional iterative packing (Verlet integration with damping) to obtain realistic, non-overlapping grain seed placement before tessellation.
10-
- **Voronoi tessellation** -- Delaunay triangulation (DeWall algorithm) followed by dual Voronoi construction via `MicroGraph`.
11-
- **Subdivision surfaces** -- Voronoi facets are converted to Loop subdivision surfaces (`SubZero`) so grain boundaries can be smoothly refined to arbitrary resolution.
12-
- **Crystallographic texture** -- orientations sampled from a Bingham distribution are assigned per grain; IPF coloring is rendered into VTK attributes.
13-
- **Phase transformation** -- a parent microstructure can be overlaid with a finer product microstructure and each product grain inherits the parent grain identity.
14-
- **Export formats**
15-
- VTK Unstructured Grid (`.vtu`) for 3D/2D visualization in ParaView.
16-
- ANG (`.ang`) for 2D EBSD-like data analysis (rasterized from the subdivision mesh).
7+
VirMat generates synthetic polycrystalline microstructures -- the kind of grain structures you see when you look at a metal under a microscope. Given a statistical description of grain sizes (e.g., "log-normal distribution with mean 5 micrometers"), VirMat produces a realistic 3D (or 2D) arrangement of grains with smooth boundaries, crystallographic orientations, and morphological properties.
178

18-
## Architecture Overview
9+
The output can be visualized in [ParaView](https://www.paraview.org/) (VTK format) or analyzed with EBSD software like OIM or MTEX (ANG format).
1910

20-
### Generation Pipeline
11+
## Why generate virtual microstructures?
2112

22-
```
23-
JobRequest (CLI)
24-
|
25-
v
26-
Grain Size Sampling -- Core.Sampling + Distributions.GrainSize
27-
| (inverse-CDF sampling from composed multi-distributions)
28-
v
29-
Weighted Point Cloud -- GrainDistributionGenerator
30-
| (circles/spheres with diameter-derived radii)
31-
v
32-
[Optional] Sphere Packing -- Core.Packer (Verlet integration, N iterations)
33-
|
34-
v
35-
Delaunay Triangulation -- DeUni (DeWall algorithm, 2D or 3D)
36-
|
37-
v
38-
Voronoi Micro-graph -- Core.VoronoiMicro (dual of Delaunay -> MicroGraph)
39-
|
40-
v
41-
FlexMicro (Subdivision) -- Core.FlexMicro (Loop subdivision surfaces via SubZero)
42-
|
43-
+---> Texture Assignment -- Distributions.Texture.ODFSampling (Bingham sampling)
44-
|
45-
+---> Morphology Query -- Distributions.GrainSize.GrainQuery (area, volume, neighbors)
46-
|
47-
+---> VTK Rendering -- FlexMicro.renderFlexMicro -> .vtu files
48-
|
49-
+---> ANG Rasterization -- IO.Export.ANG.RasterEngine -> .ang files
50-
|
51-
+---> Phase Transformation -- PhaseTrans (parent/product overlay)
52-
```
53-
54-
### Data Flow Types
55-
56-
| Type | Description |
57-
|------|-------------|
58-
| `JobRequest` | Parsed CLI parameters: dimension, grain count/box size, distribution, seed |
59-
| `DistributedPoints v` | Bounding box + weighted point cloud (`SetPoint v`) |
60-
| `Simulation v` | Full state: box, points, Delaunay triangulation, Voronoi micro-graph |
61-
| `FlexMicro v a` | Subdivision-surface microstructure with per-grain property `a` |
62-
| `GrainMorph v` | Computed morphological properties (center, length, area, volume, neighbor count) |
63-
64-
## Packages
65-
66-
VirMat is organized as a multi-package Haskell project. The root package orchestrates the generation pipeline, while specialized functionality is pulled from several core libraries via `cabal.project` (previously git submodules):
67-
68-
| Package | Description |
69-
|---------|-------------|
70-
| [DeUni](https://github.com/lostbean/DeUni) | 3D Convex Hull and Delaunay triangulation using the Marriage-Before-Conquer (MBC) / DeWall algorithm |
71-
| [hammer](https://github.com/lostbean/hammer) | Metallurgical utilities: `MicroGraph` topology, grain finding, sparse matrices, and VTK generation |
72-
| [sledge](https://github.com/lostbean/sledge) | Crystallographic orientations, symmetries, Bingham distributions, IPF coloring, and EBSD file formats (ANG, CTF) |
73-
| [linear-vect](https://github.com/lostbean/linear-vect) | Low-dimensional linear algebra: `Vec2`, `Vec3`, `Vec4`, matrices, quaternions |
74-
| [queryforest](https://github.com/lostbean/queryforest) | Spatial indexing and nearest-neighbor search (KD-trees, VP-trees) |
75-
| [SubZero](https://github.com/lostbean/SubZero) | Subdivision surfaces for 1D (lines/curves) and 2D (triangular meshes, Loop scheme) |
76-
| [VTK](https://github.com/lostbean/VTK) | Library for generating VTK XML files (`.vtu`, `.vti`, etc.) |
77-
| [mcl](https://github.com/lostbean/mcl) | Markov Cluster Algorithm (MCL) for graph clustering |
78-
79-
## Key Modules and Source Files
80-
81-
### Entry Point
82-
83-
| File | Module | Role |
84-
|------|--------|------|
85-
| `src/Main.hs` | `Main` | CLI entry point; dispatches to `go2D` or `go3D` based on `--2d`/`--3d` flag |
86-
87-
### Core Library (`VirMat.*`)
88-
89-
| File | Module | Role |
90-
|------|--------|------|
91-
| `src/VirMat/Types.hs` | `VirMat.Types` | `Simulation` record: box, point set, triangulation, grain set |
92-
| `src/VirMat/Run2D.hs` | `VirMat.Run2D` | 2D pipeline: sample points, optional packing, Delaunay, Voronoi |
93-
| `src/VirMat/Run3D.hs` | `VirMat.Run3D` | 3D pipeline: same stages for 3D |
94-
| `src/VirMat/Core/Sampling.hs` | `VirMat.Core.Sampling` | Statistical distributions (LogNormal, Normal, Uniform, Custom), inverse-CDF sampling |
95-
| `src/VirMat/Core/Packer.hs` | `VirMat.Core.Packer` | Iterative sphere/circle packing via Verlet integration with force model and damping |
96-
| `src/VirMat/Core/VoronoiMicro.hs` | `VirMat.Core.VoronoiMicro` | Converts Delaunay simplices to Voronoi `MicroGraph` (dual construction) |
97-
| `src/VirMat/Core/FlexMicro.hs` | `VirMat.Core.FlexMicro` | Converts Voronoi polygons/polyhedra to Loop subdivision surfaces; VTK rendering |
98-
99-
### Distributions
100-
101-
| File | Module | Role |
102-
|------|--------|------|
103-
| `src/VirMat/Distributions/GrainSize/GrainDistributionGenerator.hs` | `...GrainDistributionGenerator` | Generates weighted point clouds by grain count or bounding box volume |
104-
| `src/VirMat/Distributions/GrainSize/GrainQuery.hs` | `...GrainQuery` | Computes per-grain morphological properties from subdivision meshes |
105-
| `src/VirMat/Distributions/Texture/ODFSampling.hs` | `...ODFSampling` | Assigns Bingham-sampled crystallographic orientations to grains; IPF RGB coloring |
106-
107-
### I/O
108-
109-
| File | Module | Role |
110-
|------|--------|------|
111-
| `src/VirMat/IO/Import/CommandLine.hs` | `...CommandLine` | CLI parser (optparse-applicative) |
112-
| `src/VirMat/IO/Import/Types.hs` | `...Import.Types` | `JobRequest`, `Dimension`, `StructureSize`, `DistributionType`, `Output` |
113-
| `src/VirMat/IO/Export/ANG/RasterEngine.hs` | `...ANG.RasterEngine` | Triangle rasterization engine that converts `FlexMicro` grains to an ANG grid |
114-
| `src/VirMat/IO/Export/VTK/VTKODFRender.hs` | `...VTK.VTKODFRender` | Renders a discrete ODF to a VTK ImageData (`.vti`) file |
115-
116-
### Other
117-
118-
| File | Module | Role |
119-
|------|--------|------|
120-
| `src/VirMat/PhaseTrans.hs` | `VirMat.PhaseTrans` | Phase transformation simulation: parent/product microstructure overlay |
121-
122-
## Building
123-
124-
### Prerequisites
125-
126-
- [Cabal](https://www.haskell.org/cabal/) or [Stack](https://docs.haskellstack.org/en/stable/)
127-
- GHC 9.10.x (recommended)
128-
129-
### With Cabal
130-
131-
```bash
132-
git clone <repo-url>
133-
cd VirMat
134-
135-
# Build the entire project and dependencies
136-
cabal build
137-
138-
# Run the executable
139-
cabal run virmatgen -- --help
140-
```
141-
142-
### With Stack
13+
Real microstructure characterization is expensive and limited: EBSD scans are 2D slices, serial sectioning is destructive, and 3D EBSD is still slow and costly. Virtual microstructures provide:
14314

144-
```bash
145-
git clone <repo-url>
146-
cd VirMat
15+
- **Input for simulations** -- finite element models, crystal plasticity simulations, and phase-field models need realistic starting microstructures
16+
- **Statistical validation** -- compare simulated grain size distributions, neighbor counts, and morphological properties against experimental data
17+
- **Parametric studies** -- vary grain size, texture, or packing without needing new experiments
18+
- **3D structure from 2D statistics** -- generate full 3D microstructures from grain size distributions measured on 2D cross-sections
14719

148-
# Build the entire project
149-
stack build
20+
## The generation pipeline
15021

151-
# Run the executable
152-
stack exec virmatgen -- --help
153-
```
22+
### 1. Grain size sampling
15423

155-
### With Nix (development shell)
24+
Grain sizes are drawn from user-specified statistical distributions. Supported distributions:
15625

157-
The project provides a Nix flake for a reproducible development environment:
26+
- **Log-normal** -- the most common grain size distribution in real materials
27+
- **Normal** -- symmetric distribution
28+
- **Uniform** -- constant probability within bounds
29+
- **Custom** -- arbitrary histogram
30+
- **Composed** -- combine multiple distributions for multi-modal populations (e.g., bimodal grain sizes after partial recrystallization)
15831

159-
```bash
160-
# Enter the dev shell (provides GHC, Stack, Cabal, HLS, zlib, clang, treefmt)
161-
nix develop
32+
Sampling uses inverse-CDF (cumulative distribution function) interpolation.
16233

163-
# Then build with Cabal or Stack as usual
164-
cabal build
165-
```
34+
### 2. Sphere packing
16635

167-
## Testing
36+
Grain seed points are placed as spheres/circles with diameters corresponding to the sampled grain sizes. An optional iterative packing step uses Verlet integration with a force model (quadratic repulsion for overlaps, attraction for free space) to arrange grains into a realistic, non-overlapping configuration.
16837

169-
VirMat includes a comprehensive test suite using `hspec` and `QuickCheck`.
38+
### 3. Voronoi tessellation
17039

171-
```bash
172-
# Run all tests
173-
cabal test
40+
The packed seed points are triangulated using Delaunay triangulation (via `DeUni`), then the geometric dual -- the Voronoi tessellation -- is extracted. Each Voronoi cell becomes a grain. The Voronoi dual is stored as a microstructure graph (via `hammer`) encoding grains, grain boundaries (faces), triple lines (edges), and quadruple points (vertices).
17441

175-
# Run tests with coverage report
176-
cabal test --enable-coverage
177-
```
42+
### 4. Subdivision smoothing
17843

179-
The test suite covers:
180-
- **Core.Packer**: Force models and bounding box constraints.
181-
- **Core.Sampling**: Statistical distribution area, mean, and composition.
182-
- **Distributions.GrainSize**: Bounding box geometry and volumetric consistency.
183-
- **GrainQuery**: Geometric primitives (triangle area, tetrahedron volume).
44+
The flat-faceted Voronoi polyhedra are refined using Loop subdivision surfaces (via `SubZero`). A few levels of subdivision produce smooth, realistic grain boundaries suitable for visualization and analysis.
18445

185-
## CLI Usage
46+
### 5. Texture assignment
18647

187-
The primary executable is `virmatgen`. It generates microstructures based on command-line parameters.
48+
Each grain is assigned a crystallographic orientation sampled from a Bingham distribution (via `sledge`). Inverse Pole Figure (IPF) colors are computed and attached as VTK attributes for visualization.
18849

189-
```
190-
virmatgen - Virtual microstructure generator in 3D/2D.
191-
192-
Usage: virmatgen [--3d | --2d]
193-
[--n2d INT | --n2d (DOUBLE,DOUBLE)]
194-
[--packed-n INT | --packed | --random]
195-
[--lnorm (k,mu,mode,o) | --norm (k,mu,s) | --uniform (k,mu,s)] ...
196-
[--seed INT]
197-
-d FILEPATH -s STR
198-
[--showvoronoi] [--showbox] [--showhull]
199-
[--showpoints] [--showsimplex] [--showforces]
200-
```
50+
### 6. Export
20151

202-
### Key Options
52+
- **VTK** (`.vtu`) -- 3D and 2D microstructures with grain ID, volume, area, neighbor count, and IPF coloring
53+
- **ANG** (`.ang`) -- 2D orientation map rasterized from the subdivision mesh, compatible with EBSD analysis tools
20354

204-
| Flag | Description | Default |
205-
|------|-------------|---------|
206-
| `--3d` / `--2d` | Dimensionality of the microstructure | `--3d` |
207-
| `--n2d INT` | Number of grains | `500` |
208-
| `--packed` | Enable sphere packing (60 iterations) | enabled |
209-
| `--packed-n INT` | Sphere packing with custom iteration count | -- |
210-
| `--random` | Random (non-packed) grain placement | -- |
211-
| `--lnorm (k,mu,mode,o)` | Log-Normal grain size distribution | -- |
212-
| `--norm (k,mu,s)` | Normal grain size distribution | -- |
213-
| `--uniform (k,mu,s)` | Uniform grain size distribution | -- |
214-
| `--seed INT` | Random seed for reproducibility | system random |
215-
| `-d FILEPATH` | Output directory | required |
216-
| `-s STR` | Sample name | required |
217-
218-
Distribution parameters: `k` = scaling factor, `mu` = average/mean, `s` = variance, `mode` = distribution mode, `o` = offset. Multiple `--lnorm`, `--norm`, and `--uniform` flags can be combined for multi-modal distributions.
55+
## Ecosystem packages
21956

220-
### Output Files
57+
VirMat orchestrates several specialized libraries:
22158

222-
| File | Format | Content |
223-
|------|--------|---------|
224-
| `virmat-3d.vtu` | VTK Unstructured Grid | 3D microstructure with grain ID, volume, area, neighbor count, and IPF-ND coloring |
225-
| `virmat-2d.vtu` | VTK Unstructured Grid | 2D microstructure with grain ID, area, boundary length, and neighbor count |
226-
| `virmat-2d.ang` | ANG (EBSD) | Rasterized 2D orientation map for EBSD analysis tools (OIM, MTEX, etc.) |
59+
| Package | Role |
60+
|---------|------|
61+
| [DeUni](https://github.com/lostbean/DeUni) | Delaunay triangulation (Marriage Before Conquer algorithm) |
62+
| [hammer](https://github.com/lostbean/hammer) | Microstructure graph, grain finding, VTK export |
63+
| [sledge](https://github.com/lostbean/sledge) | Crystallographic orientations, Bingham distributions, EBSD I/O |
64+
| [linear-vect](https://github.com/lostbean/linear-vect) | Low-dimensional linear algebra (vectors, matrices) |
65+
| [queryforest](https://github.com/lostbean/queryforest) | Spatial indexing (VP-trees, KD-trees) |
66+
| [SubZero](https://github.com/lostbean/SubZero) | Subdivision surfaces (Loop scheme) |
67+
| [VTK](https://github.com/lostbean/VTK) | VTK XML file generation |
68+
| [mcl](https://github.com/lostbean/mcl) | Markov Cluster Algorithm for graph clustering |
22769

228-
### Example
70+
## Example
22971

23072
```bash
231-
# Generate a 3D microstructure with 200 grains, log-normal size distribution, packed
232-
stack exec virmatgen -- --3d --n2d 200 --packed \
73+
# 3D microstructure, 200 grains, log-normal distribution, packed
74+
virmatgen --3d --n2d 200 --packed \
23375
--lnorm '(1.0, 5.0, 3.0, 0.0)' \
23476
--seed 42 \
23577
-d ./output -s mysample
23678

237-
# Generate a 2D microstructure with normal distribution, 100 grains
238-
stack exec virmatgen -- --2d --n2d 100 --packed \
79+
# 2D microstructure, 100 grains, normal distribution
80+
virmatgen --2d --n2d 100 --packed \
23981
--norm '(1.0, 5.0, 1.0)' \
24082
--seed 42 \
24183
-d ./output -s mysample2d
24284
```
24385

244-
## Dependencies
86+
### Key CLI options
24587

246-
### Haskell (from Hackage)
88+
| Flag | Description | Default |
89+
|------|-------------|---------|
90+
| `--3d` / `--2d` | Dimensionality | 3D |
91+
| `--n2d INT` | Number of grains | 500 |
92+
| `--packed` / `--packed-n INT` | Enable packing (with optional iteration count) | 60 iterations |
93+
| `--random` | Random placement (no packing) | -- |
94+
| `--lnorm (k,mu,mode,o)` | Log-normal distribution | -- |
95+
| `--norm (k,mu,s)` | Normal distribution | -- |
96+
| `--uniform (k,mu,s)` | Uniform distribution | -- |
97+
| `--seed INT` | Random seed | system random |
98+
| `-d FILEPATH` | Output directory | required |
99+
| `-s STR` | Sample name | required |
247100

248-
`base`, `containers`, `mersenne-random-pure64`, `mtl`, `optparse-applicative`, `random`, `random-fu`, `transformers`, `unordered-containers`, `vector`
101+
Multiple distribution flags can be combined for multi-modal grain size populations.
249102

250-
### Internal Packages
103+
## How to build
251104

252-
These are managed via `cabal.project` and `stack.yaml` as source-repository-packages:
253-
`DeUni`, `hammer`, `sledge`, `linear-vect`, `SubZero`, `queryforest`, `VTK`, `mcl`
105+
```bash
106+
# With Nix (recommended)
107+
nix develop
108+
cabal build
254109

255-
## Author
110+
# With Stack
111+
stack build
256112

257-
Edgar Gomes de Araujo (<talktoedgar@gmail.com>)
113+
# Run the executable
114+
cabal run virmatgen -- --help
115+
116+
# Run tests
117+
cabal test
118+
```
258119

259120
## License
260121

0 commit comments

Comments
 (0)