Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ad84377
Add pyproject.toml to fix pip install from source
ksugahar Feb 10, 2026
ad7b714
Merge upstream/master (NGSolve 7651cfdf0)
ksugahar Feb 10, 2026
caefbab
Add NGSolve MCP Server with 15 tools including Kelvin transformation
ksugahar Feb 12, 2026
3dd15a5
docs: Add branch management policy for MCP server development
ksugahar Feb 12, 2026
b69cf2a
docs: Clarify branch policy for research lab internal use
ksugahar Feb 12, 2026
90a81ae
docs: Enhanced README with detailed usage examples and technical back…
ksugahar Feb 12, 2026
c0f7698
feat: Add diagnostic and debugging tools to NGSolve MCP server
ksugahar Feb 12, 2026
53d96ef
docs: Add CHANGELOG.md for version tracking
ksugahar Feb 12, 2026
7c8f7fe
docs: Add comprehensive troubleshooting section to README
ksugahar Feb 12, 2026
614e306
docs: Extract NGSolve patterns from EMPY_Analysis
ksugahar Feb 12, 2026
37cc0b1
feat: Add T-Omega eddy current analysis tools with hole support
ksugahar Feb 12, 2026
a973c64
feat: Add 2-scalar potential method for magnetostatic analysis
ksugahar Feb 12, 2026
50717ee
feat: Add coil jump support for 2-scalar magnetostatic method
ksugahar Feb 12, 2026
1376255
fix: Correct tool routing for two-scalar coil jump tools
ksugahar Feb 12, 2026
9a73c67
Merge remote-tracking branch 'upstream/master'
ksugahar Feb 19, 2026
c4975a9
Remove mcp_server_ngsolve from repository
ksugahar Feb 19, 2026
6844986
Add Netgen .vol to Gmsh/VTK converter utility
ksugahar Feb 19, 2026
960fc59
Fix unused imports in test_vol_to_gmsh.py
ksugahar Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[build-system]
requires = [
"setuptools",
"wheel",
"scikit-build",
"cmake",
"pybind11-stubgen==2.5",
"netgen-mesher",
"mkl",
"intel-cmplr-lib-rt",
"requests",
"packaging",
]
build-backend = "setuptools.build_meta"
123 changes: 123 additions & 0 deletions utils/vol_to_gmsh/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Netgen .vol to Gmsh/VTK Converter

## Overview

Convert Netgen `.vol` mesh files to Gmsh `.msh` or VTK `.vtk` format for visualization.

## Requirements

- NGSolve / Netgen (installed)
- Gmsh (optional, for viewing .msh files)
- ParaView (optional, for viewing .vtk files)

## Usage

### Basic Gmsh Conversion

```bash
# Convert .vol to .msh (Gmsh format)
python vol_to_gmsh.py input.vol

# Output: input.msh
```

### VTK Conversion

```bash
# Convert .vol to .vtk (VTK format)
python vol_to_gmsh.py input.vol --vtk

# Output: input.vtk
```

### Custom Output Name

```bash
# Specify output filename
python vol_to_gmsh.py input.vol output.msh
python vol_to_gmsh.py input.vol output.vtk --vtk
```

### View in Gmsh

```bash
# Convert and open in Gmsh
python vol_to_gmsh.py input.vol --view
```

## Examples

### Example 1: Convert cube mesh

```bash
python vol_to_gmsh.py cube.vol
```

### Example 2: Convert to VTK format for ParaView

```bash
python vol_to_gmsh.py mesh.vol --vtk
```

## Gmsh Format Details

The script exports to **Gmsh Format 2.x** (ASCII format):

- Section `$Nodes`: Vertex coordinates (1-indexed)
- Section `$Elements`: Elements with type IDs
- Supports up to 2nd order elements

### Element Type IDs (Gmsh 2.x)

| Type ID | Element | Nodes |
|---------|---------|-------|
| 2 | Triangle | 3 |
| 4 | Tetrahedron | 4 |
| 5 | Hexahedron | 8 |
| 6 | Wedge/Prism | 6 |

For details, see the [Gmsh documentation](https://gmsh.info/doc/texinfo/gmsh.html).

## VTK Format Details

VTK format is suitable for:
- ParaView visualization
- Python analysis with PyVista
- Legacy VTK readers

## Tested Files

Successfully converted:
- `cube.vol` (228 vertices, 756 elements)
- `coil.vol` (331 vertices, 1709 elements)
- `shaft.vol` (558 vertices, 1622 elements)
- `square.vol` (2D mesh)

## Troubleshooting

### Error: File not found

Check that the input `.vol` file exists:
```bash
ls -l input.vol
```

### Error: Gmsh not found in PATH

Install Gmsh from https://gmsh.info/ or disable `--view` option.

### Unicode encoding errors (Windows)

Script now uses ASCII characters `[OK]` instead of Unicode checkmarks for Windows cp932 compatibility.

## Related Tools

- **Gmsh**: https://gmsh.info/
- **ParaView**: https://www.paraview.org/
- **PyVista**: https://docs.pyvista.org/

## Notes

- Gmsh format version can be selected with `--format gmsh` or `--format gmsh2`
- Default: Gmsh 2.x format (widely supported)
- VTK format includes mesh geometry only (no field data)
68 changes: 68 additions & 0 deletions utils/vol_to_gmsh/test_vol_to_gmsh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Tests for vol_to_gmsh converter."""

import os
import pytest
from pathlib import Path
from vol_to_gmsh import convert_vol_to_gmsh, convert_vol_to_vtk


@pytest.fixture
def sample_mesh(tmp_path):
"""Create a simple test mesh."""
from netgen.csg import unit_cube
mesh = unit_cube.GenerateMesh(maxh=0.5)
vol_file = str(tmp_path / "test.vol")
mesh.Save(vol_file)
return vol_file


def test_convert_to_gmsh(sample_mesh, tmp_path):
"""Test basic Gmsh conversion."""
output = str(tmp_path / "test.msh")
result = convert_vol_to_gmsh(sample_mesh, output)
assert os.path.exists(result)
assert result == output

with open(result) as f:
content = f.read()
assert "$MeshFormat" in content
assert "$Nodes" in content
assert "$Elements" in content


def test_convert_to_gmsh_default_name(sample_mesh):
"""Test Gmsh conversion with auto-generated filename."""
result = convert_vol_to_gmsh(sample_mesh)
expected = str(Path(sample_mesh).with_suffix('.msh'))
assert result == expected
assert os.path.exists(result)


def test_convert_to_vtk(sample_mesh, tmp_path):
"""Test VTK conversion."""
output = str(tmp_path / "test")
result = convert_vol_to_vtk(sample_mesh, output)
assert os.path.exists(result)
assert result.endswith('.vtu')


def test_missing_file():
"""Test error handling for missing file."""
with pytest.raises(RuntimeError):
convert_vol_to_gmsh("nonexistent.vol")


def test_mixed_elements(tmp_path):
"""Test conversion of mesh with multiple element types."""
from netgen.occ import Box, OCCGeometry, Pnt

box = Box(Pnt(0, 0, 0), Pnt(1, 1, 1))
geo = OCCGeometry(box)
mesh = geo.GenerateMesh(maxh=0.5)

vol_file = str(tmp_path / "mixed.vol")
mesh.Save(vol_file)

output = str(tmp_path / "mixed.msh")
result = convert_vol_to_gmsh(vol_file, output)
assert os.path.exists(result)
Loading