Skip to content

Commit 4625cb5

Browse files
committed
v0.1.0
0 parents  commit 4625cb5

22 files changed

Lines changed: 7499 additions & 0 deletions

.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Keep only final wasm artifacts in dist
2+
dist/*
3+
!dist/mystran.js
4+
!dist/mystran.wasm
5+
6+
# Docker/host build working directory
7+
build/
8+
9+
# Native reference used by smoke script
10+
sources/MYSTRAN_native_ref/
11+
12+
# Fetched third-party sources (recreated by scripts/fetch_deps.ps1)
13+
sources/MYSTRAN/
14+
sources/MYSTRAN_Benchmark/
15+
16+
# Generated from embedded assets in tools/build.js
17+
tools/build_assets/

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Copyright (c) 2026 PR-DC contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

PATCHING.md

Lines changed: 358 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# WebMYSTRAN (WebAssembly)
2+
3+
Builds [MYSTRAN](https://github.com/MYSTRANsolver/MYSTRAN) into WebAssembly and provides:
4+
5+
- reproducible fetch/build scripts
6+
- quick smoke and full benchmark-deck smoke validation
7+
- an ESM JavaScript library (`src/web_mystran.js`, `src/mystran_input.js`, `src/output_parser.js`)
8+
9+
## Requirements
10+
11+
- Docker (or compatible daemon)
12+
- Node.js 18+
13+
- PowerShell (Windows helper scripts)
14+
15+
## Quick Start (Windows)
16+
17+
1. `powershell -File scripts/fetch_deps.ps1`
18+
2. `powershell -File scripts/build.ps1`
19+
3. `node tools/smoke_test.js`
20+
21+
For full benchmark-deck smoke checks:
22+
23+
- `powershell -File scripts/smoke_test.ps1`
24+
25+
## npm Scripts
26+
27+
- `npm run fetch-deps`
28+
- `npm run build`
29+
- `npm run smoke` (library-level smoke)
30+
- `npm run smoke:full` (full deck smoke)
31+
32+
If PowerShell blocks `npm.ps1` by execution policy, run `npm.cmd` instead (for example: `npm.cmd run smoke`).
33+
34+
## Build Outputs
35+
36+
- `dist/mystran.js` (ES module, `MODULARIZE=1`, `EXPORT_ES6=1`)
37+
- `dist/mystran.wasm`
38+
- `sources/MYSTRAN_native_ref/Binaries/mystran` (native Linux reference binary for smoke compare)
39+
40+
## Module Exports
41+
42+
- `./index.js` -> `WebMYSTRAN`, `MystranInput`, `parseMystranOutput`
43+
- `./src/web_mystran.js` -> `WebMYSTRAN`
44+
- `./src/mystran_input.js` -> `MystranInput`
45+
- `./src/output_parser.js` -> `parseMystranOutput`
46+
47+
## JavaScript API (`index.js` exports)
48+
49+
### `WebMYSTRAN`
50+
51+
- `static async load(options?) -> Promise<WebMYSTRAN>`
52+
- `static input(lines?) -> MystranInput`
53+
- `static Input` (alias for `MystranInput`)
54+
- `input(lines?) -> MystranInput`
55+
- `run(deckText, options?) -> result`
56+
- `readOutput(result, extension, encoding?)`
57+
- `writeFile(path, data)`, `readFile(path, encoding?)`, `FS`, `reset()`, `destroy()`
58+
59+
`WebMYSTRAN.load(options?)` accepts:
60+
61+
- `moduleUrl`: URL/path override for `dist/mystran.js`
62+
- `wasmUrl`: URL/path override for `dist/mystran.wasm`
63+
- `moduleFactory`: custom emscripten module factory function
64+
- `exportName`: export name when loading from `moduleUrl` (default `WebmystranModule`)
65+
- `wasmBinary`: `Uint8Array`/`ArrayBuffer`/`Buffer` override for wasm bytes
66+
- `workDir`: virtual FS working directory (default `/work`)
67+
- `onStdout`/`onStderr`: per-line callbacks
68+
- `moduleOptions`/`locateFile`: forwarded to emscripten module options
69+
70+
`run(deckText, options?)`:
71+
72+
- writes `deckText` to `deckFileName` (default `WEBMYSTRAN.DAT`)
73+
- executes wasm in-process via ESM module factory
74+
- returns:
75+
- `raw`: `{ stdout, stderr, exitCode, signal, timedOut }`
76+
- `output`: parsed status object from `parseMystranOutput(raw)`
77+
- `outputs`: discovered result files by extension (`F06`, `OP2`, ...)
78+
- `files`: artifact metadata `{ extension, name, path, size }`
79+
- `workDir`, `deckFileName`, `deckPath`
80+
81+
`run(..., options?)` options:
82+
83+
- `deckFileName`, `workDir`, `stdinText`, `args`
84+
- `files`: array of `{ path, data }` staged before execution
85+
- `parseOptions`: forwarded to parser
86+
- `outputExtensions`: custom extension scan list
87+
88+
### `MystranInput`
89+
90+
Builder for deck text.
91+
92+
- `add(line | lines[])`, `addLines(lines)`
93+
- `blank(count?)`, `comment(text?)`
94+
- `sol(value)`, `cend()`, `subcase(id)`
95+
- `set(key, value)`, `setTitle(value)`, `setSubtitle(value)`, `setLabel(value)`
96+
- `beginBulk()`, `endData()`
97+
- `param(name, value)`, `include(path)`
98+
- `toArray()`, `toString()`
99+
100+
### `parseMystranOutput(raw)`
101+
102+
Parses stdout/stderr into a structured status object:
103+
104+
- `hasNormalTermination`
105+
- `hasRuntimeAbort`
106+
- `hasSolverError`
107+
- `warningCount`
108+
- `errorCodes`, `firstErrorCode`
109+
110+
## Example
111+
112+
```js
113+
import fs from "node:fs";
114+
import { WebMYSTRAN } from "./index.js";
115+
116+
const deck = fs.readFileSync(
117+
"sources/MYSTRAN_Benchmark/Benchmark_Decks/Bush_Bar/bar_01.DAT",
118+
"utf8"
119+
);
120+
121+
const solver = await WebMYSTRAN.load();
122+
const result = solver.run(deck, { deckFileName: "WEBMYSTRAN.DAT" });
123+
124+
if (!result.output.hasNormalTermination) {
125+
throw new Error("MYSTRAN did not terminate normally.");
126+
}
127+
128+
const f06Text = solver.readOutput(result, "F06", "utf8");
129+
console.log(f06Text.slice(0, 400));
130+
solver.destroy();
131+
```
132+
133+
## Smoke Testing
134+
135+
### Library smoke
136+
137+
- `node tools/smoke_test.js`
138+
- Uses benchmark deck `Bush_Bar/bar_01.DAT`
139+
- Uses the same per-deck PASS/FAIL line format and final summary format as full smoke
140+
- Runs both wasm and native reference, then checks wasm/native parity for the deck
141+
- Validates:
142+
- process exit code
143+
- `MYSTRAN terminated normally`
144+
- no parsed `*ERROR` codes
145+
- required output artifacts (`F06`, `OP2`)
146+
147+
### Full deck smoke
148+
149+
- `scripts/smoke_test.ps1` (or `node tools/smoke_test.js full`) runs wasm and native reference over selected benchmark decks
150+
- Checks:
151+
- per-deck wasm and native run outcomes (timeouts/runtime aborts/process errors)
152+
- required output generation (`F06` plus non-empty result artifacts)
153+
- wasm/native parity checks (outcome class, termination marker, error code, OP2 presence)
154+
- Reports one terminal line per deck and a final summary line
155+
- Writes no smoke artifacts to host disk (no `smoke_run` folder or host-side deck outputs)
156+
157+
## Technical References
158+
159+
- Source/dependency provenance: [SOURCES.md](./SOURCES.md)
160+
- Patch inventory: [PATCHING.md](./PATCHING.md)
161+
- Third-party notices: [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md)
162+
163+
## Environment Variables
164+
165+
`scripts/build.ps1` forwards:
166+
167+
- `WEBMYSTRAN_DEBUG_STACKS`
168+
- `WEBMYSTRAN_TRACE_MALLOC`
169+
- `WEBMYSTRAN_PROFILE_CHECKPOINTS`
170+
171+
`scripts/smoke_test.ps1` accepts smoke arguments directly.
172+
173+
## License
174+
175+
- Project/package: MIT ([LICENSE](./LICENSE))
176+
- Upstream MYSTRAN source is MIT (see `sources/MYSTRAN/LICENSE.txt`)
177+
- Additional notices: [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md)

SOURCES.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Source Provenance (WebMYSTRAN)
2+
3+
This package builds MYSTRAN into WebAssembly and includes helper scripts for
4+
fetch, patch, build, and parity validation.
5+
6+
If you redistribute the wasm output, keep this repository (scripts + patches)
7+
and make the exact upstream sources available.
8+
9+
## Upstream Repositories
10+
11+
### MYSTRAN
12+
13+
- Name: MYSTRAN
14+
- URL: https://github.com/MYSTRANsolver/MYSTRAN.git
15+
- Local path: `sources/MYSTRAN`
16+
- Resolved branch at fetch/build time: `main`
17+
- Resolved commit: `ae40b554c76c3d27b9b0fdaf697346f8e05251ac`
18+
- License: MIT (`sources/MYSTRAN/LICENSE.txt`)
19+
20+
### MYSTRAN_Benchmark
21+
22+
- Name: MYSTRAN_Benchmark
23+
- URL: https://github.com/MYSTRANsolver/MYSTRAN_Benchmark.git
24+
- Local path: `sources/MYSTRAN_Benchmark`
25+
- Resolved branch at fetch/build time: `main`
26+
- Resolved commit: `ad765adfcd2e2fd148743f0846d6ce6e71d33c99`
27+
- License: see upstream repository
28+
29+
## Fetch and Build Chain
30+
31+
- Fetch script: `scripts/fetch_deps.ps1`
32+
- Patch generator/applier: `tools/build.js`
33+
- Containerized build driver: embedded in `tools/build.js` (`tools/build_assets/build_in_docker.sh` at runtime)
34+
- CMake entrypoint/toolchain: embedded in `tools/build.js` (`tools/build_assets/*` at runtime)
35+
36+
## Patch Policy
37+
38+
- Patches are applied in-place to fetched sources in `sources/MYSTRAN`.
39+
- Detailed patch inventory is maintained in `PATCHING.md`.
40+
41+
## Repro Note
42+
43+
To reproduce the same source state:
44+
45+
1. Clone this repository.
46+
2. Run `scripts/fetch_deps.ps1` with matching refs (`-MystranRef`, `-BenchmarkRef`) if needed.
47+
3. Confirm `git -C sources/MYSTRAN rev-parse HEAD` and
48+
`git -C sources/MYSTRAN_Benchmark rev-parse HEAD` match the commit IDs above.

THIRD_PARTY_NOTICES.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Third-Party Notices
2+
3+
The generated artifacts in `dist/` and build/runtime flow may involve these
4+
third-party components:
5+
6+
- Emscripten SDK (MIT License)
7+
- https://emscripten.org/docs/introducing_emscripten/emscripten_license.html
8+
- LLVM Project (Apache 2.0 with LLVM Exceptions)
9+
- https://llvm.org/LICENSE.txt
10+
- flang-wasm container image
11+
- `ghcr.io/r-wasm/flang-wasm:v20.1.4`
12+
- MYSTRAN upstream source (MIT License)
13+
- https://github.com/MYSTRANsolver/MYSTRAN
14+
- SuperLU / SuperLU_MT (via MYSTRAN submodules)
15+
- https://github.com/xiaoyeli/superlu
16+
- https://github.com/xiaoyeli/superlu_mt
17+
- netlib f2c source (used in build toolchain)
18+
- https://www.netlib.org/f2c/
19+
20+
This repository does not redistribute the full toolchains. Use the links above
21+
for their license texts and notices.
22+

dist/mystran.js

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/mystran.wasm

4.43 MB
Binary file not shown.

index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { WebMYSTRAN } from "./src/web_mystran.js";
2+
export { MystranInput } from "./src/mystran_input.js";
3+
export { parseMystranOutput } from "./src/output_parser.js";

package.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "webmystran-wasm",
3+
"version": "0.1.0",
4+
"description": "WebMYSTRAN WebAssembly build, smoke validation, and Node.js wrapper API.",
5+
"author": "Milos Petrasinovic <mpetrasinovic@pr-dc.com>",
6+
"keywords": [
7+
"mystran",
8+
"fea",
9+
"fem",
10+
"fortran",
11+
"wasm",
12+
"webassembly"
13+
],
14+
"license": "MIT",
15+
"type": "module",
16+
"main": "index.js",
17+
"exports": {
18+
".": "./index.js",
19+
"./mystran": "./src/web_mystran.js",
20+
"./web_mystran": "./src/web_mystran.js",
21+
"./mystran_input": "./src/mystran_input.js",
22+
"./output_parser": "./src/output_parser.js",
23+
"./wasm_runner": "./tools/wasm_runner.js",
24+
"./package.json": "./package.json"
25+
},
26+
"files": [
27+
"dist/",
28+
"src/",
29+
"tools/build.js",
30+
"tools/smoke_test.js",
31+
"tools/wasm_runner.js",
32+
"scripts/",
33+
"index.js",
34+
"README.md",
35+
"SOURCES.md",
36+
"THIRD_PARTY_NOTICES.md",
37+
"PATCHING.md",
38+
"LICENSE"
39+
],
40+
"scripts": {
41+
"fetch-deps": "powershell -ExecutionPolicy Bypass -NoProfile -File scripts/fetch_deps.ps1",
42+
"build": "node tools/build.js",
43+
"smoke": "node tools/smoke_test.js",
44+
"smoke-full": "node tools/smoke_test.js full"
45+
},
46+
"engines": {
47+
"node": ">=18"
48+
}
49+
}

0 commit comments

Comments
 (0)