Write linearization (.lin) output at full precision, independent of OutFmt#3393
Open
mayankchetan wants to merge 3 commits into
Open
Write linearization (.lin) output at full precision, independent of OutFmt#3393mayankchetan wants to merge 3 commits into
mayankchetan wants to merge 3 commits into
Conversation
…less of OutFmt The .lin Jacobian matrices (A/B/C/D, dUdu/dUdy/dXdy/J and the module-level blocks), the operating-point column, and the header values (incl. Rotor Speed, consumed by MBC3 tools) were formatted with the deck's tabular OutFmt, whose default "ES10.3E2" carries ~4 significant digits. Assembled Jacobians of coupled-section BeamDyn blades span ~15 orders of magnitude, so the write itself corrupted downstream eigenanalysis: physically impossible results (spurious positive real eigenvalues, negative damping ratios, merged or missing tower modes) for parked, passive structures on IEA-15/3.4/10/22 class models, while near-diagonal-section models (NREL 5-MW) escaped. Fix: a fixed module-level format LinFmt='ES24.15E3' (full double precision) for all numeric .lin output in FAST_ModGlue; tab-stop width updated to match. Tabular time-series output keeps honoring OutFmt, unchanged. Verification: IEA-15-240-RWT structure-only standstill case with default OutFmt, patched dev build: A-matrix eigenvalues go from 1 spurious positive real eigenvalue + merged tower mode (0.2163 Hz) to 0 unstable and a correctly split tower pair (0.2369/0.2386 Hz vs ElastoDyn 0.2350/0.2366); identical to the ES18.9E3-deck control on the unpatched binary. Rounding a clean A to 4 significant digits in numpy reproduces the corrupted eigenvalues exactly, confirming the mechanism. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves the fidelity of OpenFAST linearization (.lin) outputs by switching all numeric .lin formatting to a fixed, full double-precision scientific format, independent of the user’s tabular OutFmt, to avoid precision-loss that can corrupt downstream eigenanalysis results.
Changes:
- Introduces a fixed
.linnumeric format (LinFmt = ES24.15E3) and applies it to.linheader scalars, operating-point tables, and all written Jacobian/state matrices. - Updates the operating-point table tab-stop calculation to match the new fixed field width.
- Modifies the Apache 2.0
LICENSEappendix boilerplate line.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| modules/openfast-library/src/FAST_ModGlue.f90 | Writes all .lin numeric output using a fixed full-precision format to prevent loss of significant digits in linearization artifacts. |
| LICENSE | Updates the appendix boilerplate copyright placeholder line. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| identification within third-party archives. | ||
|
|
||
| Copyright {yyyy} {name of copyright owner} | ||
| Copyright 2025 NREL |
This was referenced Jul 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Feature or improvement description
Write linearization (
.lin) output at full precision, independent of theOutFmtset in the OpenFAST input file.The glue code currently formats everything in the
.linfiles — the Jacobian matrices(A/B/C/D,
dUdu/dUdy, module blocks), the operating-point column, and the header scalars(including Rotor Speed, which MBC3 postprocessors consume) — with the OpenFAST input's tabular
OutFmt, whose documented default"ES10.3E2"carries only ~4 significant digits.For models whose state matrices span a wide dynamic range (e.g. BeamDyn blades with fully
populated sectional mass/stiffness matrices, where the assembled A spans ~15 orders of
magnitude), 4 digits is not enough to round-trip the matrix through disk: every downstream
eigenanalysis (openfast_toolbox / pyFAST, MBC3 / Campbell workflows, ACDC) then reports
physically impossible results for a parked, passive structure — spurious positive
eigenvalues, negative damping ratios, and merged or missing modes. The corruption is
invisible in the
.linfile itself and easily misread as a physics or solver defect.This PR introduces a fixed full-double-precision format for all numeric
.linoutput:Tabular time-series output continues to honor the user's
OutFmt, unchanged. Workaround onreleased versions: set
OutFmt "ES18.9E3"in any OpenFAST input file used for linearization.Related issue, if one exists
Fixes #3395. Discovered alongside the independent BeamDyn rotating-frame defect #3394 (fix: #3396); the two PRs are independent.
Impacted areas of the software
modules/openfast-library/src/FAST_ModGlue.f90only: all matrix writes, theoperating-point column formats, and the header-scalar format now use
LinFmt; theoperating-point tab stop is sized from the new width. No change to what is computed —
only to how it is written.
.linfiles grow ~2.4× per numeric field. They are analysis artifacts, not time series,so the size cost is negligible against the correctness gain.
ES24.15E3is standard Fortran scientific notation; verifiedwith openfast_toolbox
ReadFASTLinear)..linbaselines will differ textually (wider fields, moredigits); values agree with the old files to the old files' precision, so baselines need
a regeneration pass, not tolerance changes.
Generative AI usage
Developed with Anthropic Claude (Claude Code) under human direction using OAK's workflows.
Co-authored-by: Anthropic Claude claude@anthropic.com
Test results, if applicable
uses the default
OutFmt: before the patch, eigenanalysis of the written A matrixyields a spurious positive real eigenvalue and a merged tower pair; after the patch,
the same input yields 0 unstable eigenvalues and the correctly split tower pair,
matching a control run whose input sets a wide
OutFmtexplicitly.