|
FhSim
3.1.0
Marine systems simulation
|
| ID | 0044 |
| Class | BUG |
| Severity | 3 |
| Status | blocked |
| Models | — (the FMU scenario in examples/input/FMU/) |
| Found | 2026-09-23 |
| Decision needed | The root cause is in FhSim's exporter (fhsim/src/fmu/fhFMUexport/FmuResourceCopier.cpp), not in this repository, so the fix may not be ours. What is ours is the decision of how examples/input/FMU/AuvSurvey.xml should name auv_ocean_fields.json so that an FMU can carry it: wait for the exporter to be corrected, or work around it here (for instance by adding the JSON's directory with --add-res-dir and naming it by a path relative to resources, which is a spelling --autocopy does not have to rewrite). Until one of the two happens, the exported AuvSurvey FMU has no ocean fields. |
examples/input/FMU/AuvSurvey.xml:131,137,143,151,159 name the field data by a path relative to the playpen's bin:
examples/input/FMU/AuvSurvey.fmu.yaml declares export_flags: ["--autocopy"] and states that this "copies every file a model attribute names into
`resources/auto_copied/` and rewrites the attribute to point there". That was reasoned from the exporter's source and never run. Run now, it does neither.
FhFmuExport --autocopy is implemented by FmuResourceCopier::CollectFileReferences (fhsim/src/fmu/fhFMUexport/FmuResourceCopier.cpp:59-106). For each Lib attribute it
fs::exists(fhsimPath / asPath), where fhsimPath is the playpen's bin directory, thenfs::is_regular_file(asPath) and copies with fs::copy(asPath, ...) — both relative to the process working directory, not to fhsimPath, andfs::equivalent(fhsimPath / "../resources" / asPath, fhsimPath / asPath) (line 82).Each of the three steps breaks on this model, and the two builds of this repository break in different ways.
**Visual playpen (build/Release/playpen), export succeeds and the FMU is wrong.** fhsimPath / "../resources" / "../examples/input/fishery/auv_ocean_fields.json" collapses to playpen/examples/input/fishery/auv_ocean_fields.json, which is the same file as the second operand, so fs::equivalent returns true and the attribute is taken to be inside resources already. Nothing is copied and the attribute is rewritten to a path outside the FMU:
From the instantiated FMU's binaries/linux64, that resolves to <fmu>/binaries/examples/input/fishery/auv_ocean_fields.json, which does not exist. Run with any other working directory — which is what fhsim_fmu/tools/export_fmus.py does, since it runs the exporter in its own workspace — the is_regular_file(asPath) test is false as well, so the attribute is left exactly as written and the FMU is equally wrong.
**Headless playpen (build/no_vis/Release/playpen), the export fails outright.** That playpen has no resources/ directory, so the first operand of fs::equivalent does not exist and the call throws:
AuvSurvey.fmu.yaml declares variants: [headless, visual], so this is half the published matrix.
The same fs::equivalent throw is reachable with a bare file name and no .. at all: with a leftover AuvSurvey_echogram.csv in the visual playpen's bin (the echosounder's FileName attribute, written there by the test run), the export aborts on .../bin/../resources/AuvSurvey_echogram.csv not existing. So --autocopy also makes an export sensitive to output files left in the playpen by an earlier run.
Nothing exercises any of this: there is no --autocopy model in fhsim_fmu/catalogue/, no test for it in fhsim_fmu/tests/ and none in fhsim/tests/. This model is the first user of the flag.
The exported AuvSurvey FMU cannot read its ocean fields. The headless variant cannot be exported at all. Both are independent of the FMU interface itself, which is correct: the export produces a modelDescription.xml with all 21 variables — the seven vehicle outputs, the three instrument measurements and the two host overrides — and fmpy validate passes on it.
Upstream, in FmuResourceCopier::CollectFileReferences: resolve the attribute against fhsimPath once and use that resolved path for the classification, the equivalence test and the copy; guard the fs::equivalent call with an existence test on both operands (or use std::filesystem::weakly_canonical and compare); and compare against the canonical resources directory rather than against a ../resources/.. path that collapses back out of it.
In this repository, once that is settled: keep the attribute as written and rely on a corrected --autocopy, or name the JSON by a spelling the exporter cannot misclassify.
Export examples/input/FMU/AuvSurvey.xml from both playpens with --autocopy and assert that the export succeeds, that resources/auto_copied/auv_ocean_fields.json exists in the archive, and that the model's five ConfigFile attributes point at it. FISH-0043 asks for a parse test over this same file and is the natural place to hang it.
The upstream change touches every --autocopy export. Since this model is the flag's only user, the blast radius is this model.