[](https://crates.io/crates/caexfer)
[](https://docs.rs/caexfer)
[](https://github.com/cmccomb/caexfer/actions/workflows/ci.yml)
[](https://github.com/cmccomb/caexfer/actions/workflows/coverage.yml)
# caexfer
<p align="center"><img src="https://raw.githubusercontent.com/cmccomb/caexfer/main/assets/logo.svg" alt="caexfer logo" width="320"></p>
**Transfer finite-element meshes and results across formats.**
`caexfer` reads and writes supported subsets of STL, SU2, UNV, Exodus II,
VTU, legacy VTK, Gmsh MSH 4.1/2.2, Abaqus/CalculiX INP, CalculiX FRD,
Nastran BDF, and Nastran OP2. It also reads PCH displacement results when
given a matching mesh. Each conversion reports omissions and assumptions.
## Get started
Requires Rust 1.86 or newer. Install the published CLI from crates.io:
```sh
cargo install caexfer
caexfer --formats
```
Add the published library to your Rust project:
```sh
cargo add caexfer
```
The CLI and library can perform the same conversions. This sequence carries
nodal results from FRD through VTU to Gmsh MSH 2.2, then reads PCH results
with a matching BDF mesh.
**CLI**
```sh
caexfer convert tests/fixtures/linear-results.frd results.vtu
caexfer convert results.vtu results.msh --msh-version 2.2
caexfer convert tests/fixtures/pch-multiple.pch displacements.vtu \
--mesh tests/fixtures/pch-companion.bdf --subcase 1
```
**Rust library**
```rust
use caexfer::{MshVersion, Options, Result, convert, validate};
fn main() -> Result<()> {
let source = validate("tests/fixtures/linear-results.frd", &Options::default())?;
assert!(source.passed);
let report = convert("tests/fixtures/linear-results.frd", "results.vtu",
&Options { accept_omissions: true, ..Options::default() })?;
for notice in report.omissions {
eprintln!("{}: {}", notice.stage.name(), notice.detail);
}
convert("results.vtu", "results.msh", &Options {
msh_version: Some(MshVersion::V2_2),
accept_omissions: true,
..Options::default()
})?;
convert("tests/fixtures/pch-multiple.pch", "displacements.vtu", &Options {
mesh: Some("tests/fixtures/pch-companion.bdf".into()),
subcase: Some(1),
accept_omissions: true,
..Options::default()
})?;
Ok(())
}
```
`convert` lists reported losses and assumptions before asking for confirmation.
For scripts, pass the specific `--accept-...` flags named in that list, or use
`--accept-all` to accept every reported change.
## Conversion routes
[](https://github.com/cmccomb/caexfer/blob/main/assets/conversion-flow.svg)
`caexfer --formats` lists the current readers and writers. Mesh sources can be
converted when the destination supports their cell types and data. VTU, legacy
VTK, MSH, and classic Exodus carry numeric fields within their documented
subsets; FRD carries nodal fields. BDF, INP, STL, SU2, and UNV provide narrower
geometry routes. MSH physical groups become named selections, and SU2 carries
named boundary markers. OP2 and PCH displacement results require a companion
mesh with original node IDs; OP2 can write a selected displacement table, while
PCH is read-only.