From 950ce29df1e5b7244f0bc264d47e8678f1b6c43d Mon Sep 17 00:00:00 2001 From: NINI Date: Mon, 4 May 2026 12:34:39 +0900 Subject: [PATCH] test: onboard quad 02 phase1 reference --- PLAN.md | 16 +- PROGRESS.md | 34 ++- docs/ABAQUS_INPUT_SUBSET.md | 2 + docs/VERIFICATION_PLAN.md | 3 + .../index.json | 2 +- references/README.md | 7 + references/quad_02_notes.md | 85 ++++++ references/quad_02_phase1.inp | 252 ++++++++++++++++++ tests/test_main.cpp | 28 ++ 9 files changed, 417 insertions(+), 12 deletions(-) create mode 100644 references/quad_02_notes.md create mode 100644 references/quad_02_phase1.inp diff --git a/PLAN.md b/PLAN.md index 03b9c1a..67c47e5 100644 --- a/PLAN.md +++ b/PLAN.md @@ -13,7 +13,7 @@ Every new agent session must read this file together with `PROGRESS.md` before p - If an item becomes obsolete, move it to `PROGRESS.md` with a short reason instead of silently deleting it. ## Current Objective -Continue the new Phase 1 rebaseline plan in `phases/1-linear-static-mitc4-rebaseline`, starting with P1R-01 reference onboarding. The old `phases/1-linear-static-mitc4` path is historical and superseded by the paper-based MITC4 formulation reset. +Continue the new Phase 1 rebaseline plan in `phases/1-linear-static-mitc4-rebaseline`, starting with P1R-02 core harness guardrails. The old `phases/1-linear-static-mitc4` path is historical and superseded by the paper-based MITC4 formulation reset. ## Required Reading For New Agents 1. `AGENTS.md` @@ -36,7 +36,7 @@ Continue the new Phase 1 rebaseline plan in `phases/1-linear-static-mitc4-rebase ## Active Phase Files - Active phase directory: `phases/1-linear-static-mitc4-rebaseline` - Execute with: `python scripts/execute.py 1-linear-static-mitc4-rebaseline` -- Step numbering is zero-based. `step0.md` is complete and recorded in `phases/1-linear-static-mitc4-rebaseline/step0-audit.md`; `step15.md` is the independent evaluator closeout. +- Step numbering is zero-based. `step0.md` is complete and recorded in `phases/1-linear-static-mitc4-rebaseline/step0-audit.md`; `step1.md` is complete and created the `quad_02_phase1.inp` normalized reference path; `step15.md` is the independent evaluator closeout. - Every step file contains a sprint contract with objective, required reading, scope, allowed files, explicit non-goals, tests to write first, reference artifacts, acceptance command, evaluator checklist, and handoff requirements. - Historical phase directory: `phases/1-linear-static-mitc4` - Historical phase status: blocked/superseded. Do not resume the old P1-15/P1-16 path unless the user explicitly requests recovery of that exact phase. @@ -45,7 +45,6 @@ Continue the new Phase 1 rebaseline plan in `phases/1-linear-static-mitc4-rebase | ID | Status | Owner | Task | Source | |---|---|---|---|---| | R-010 | pending | user + verification agent | Add or define reaction-force reference artifacts, preferably `*_reactions.csv`, or decide that Phase 1 `RF` is verified by equilibrium tests until Abaqus RF CSV is available. | `docs/VERIFICATION_PLAN.md`, `docs/RESULTS_SCHEMA.md` | -| R-011 | partial | generator + Abaqus compatibility evaluator | Resolve through rebaseline step 1: review `references/quad_02.inp` and `references/quad_02_displacements.csv`; either add a normalized Phase 1-compatible derivative input or create an explicit parser compatibility plan. | `phases/1-linear-static-mitc4-rebaseline/step1.md`, `docs/ABAQUS_INPUT_SUBSET.md`, `docs/VERIFICATION_PLAN.md` | | R-013 | pending | user + verification agent | Add enough additional small Abaqus S4 reference cases for the PRD target of three stored Phase 1 references: one single-element case, one simple multi-element plate/shell case, and one curved shell benchmark. | `docs/PRD.md`, `docs/VERIFICATION_PLAN.md` | ## Phase 1 Definition Of Done @@ -73,7 +72,7 @@ Each gate should be satisfied before moving to the next implementation band unle | Gate | Status | Requirement | Evidence | |---|---|---|---| -| G0 - Planning readiness | partial | Readiness tasks R-010 and R-011 remain open; earlier formulation/build/comparator blockers are resolved. | Updated docs, PLAN.md, PROGRESS.md | +| G0 - Planning readiness | partial | Readiness task R-011 is resolved by `quad_02_phase1.inp`; R-010 and R-013 remain open. | Updated docs, PLAN.md, PROGRESS.md | | G1 - Build and validation | satisfied | Build system, test framework, and `scripts/validate_workspace.py` run real checks. | Validation command output | | G2 - Parser and domain | pending rebaseline | Must be revalidated through steps 3 and 4 against the current parser subset and stored-reference compatibility policy. | Future parser and validation tests | | G3 - DOF/math/results infrastructure | pending rebaseline | Must be revalidated through steps 2, 5, 6, and 12. | Future unit and integration tests | @@ -85,12 +84,11 @@ All milestones are intended to become one or more self-contained sprint contract | ID | Status | Owner | Objective | Depends On | Acceptance Focus | |---|---|---|---|---|---| -| P1R-01 | pending | reference generator | Onboard `quad_02` as stored S4 reference and choose normalized-input or parser-compatibility path. | P1R-00 | Original artifacts preserved; compatibility explicit | | P1R-02 | pending | core generator | Revalidate build/test harness, core aliases, DOF enum, and diagnostics. | P1R-00 | Validation command and core tests | -| P1R-03 | pending | parser generator | Revalidate Phase 1 parser and immutable Domain subset. | P1R-01, P1R-02 | Supported keywords accepted; unsupported features rejected | +| P1R-03 | pending | parser generator | Revalidate Phase 1 parser and immutable Domain subset. | P1R-02 | Supported keywords accepted; unsupported features rejected | | P1R-04 | pending | validation generator | Rebuild validation and singular diagnostic coverage. | P1R-03 | Missing-reference and singular-prone negative tests | | P1R-05 | pending | DOF generator | Rebuild six-DOF DofManager, constrained/free mapping, equation numbering, and full-vector reconstruction. | P1R-02 | DOF mapping and reaction foundation tests | -| P1R-06 | pending | results generator | Rebuild minimum results model and displacement CSV comparator. | P1R-02, P1R-01 | U/RF schema tests and CSV comparator tests | +| P1R-06 | pending | results generator | Rebuild minimum results model and displacement CSV comparator. | P1R-02 | U/RF schema tests and CSV comparator tests | | P1R-07 | pending | MITC4 generator | Implement MITC4 geometry, node order, tying points, directors, and local bases. | P1R-02 | Shape/basis/diagnostic tests | | P1R-08 | pending | MITC4 generator | Implement degenerated-continuum displacement, covariant strain rows, and MITC shear tying. | P1R-07 | Finite-difference and tying interpolation tests | | P1R-09 | pending | MITC4 generator | Implement material matrix, transform, and `2 x 2 x 2` integration scaffolding. | P1R-08 | Material/integration tests | @@ -98,7 +96,7 @@ All milestones are intended to become one or more self-contained sprint contract | P1R-11 | pending | verification generator | Add MITC4 patch, locking-sensitivity, and benchmark tests. | P1R-10 | Membrane/bending/shear/twist/locking tests | | P1R-12 | pending | assembly generator | Rebuild assembly, solver adapter boundary, constrained solve, and full-vector RF recovery. | P1R-05, P1R-10 | Assembly and full-vector reaction tests | | P1R-13 | pending | analysis generator | Rebuild linear static workflow from input to U/RF result fields. | P1R-03, P1R-04, P1R-06, P1R-12 | End-to-end linear static tests | -| P1R-14 | pending | reference generator | Run stored reference displacement regression using accepted Phase 1-compatible S4 cases. | P1R-13, P1R-01 | At least one automated CSV displacement regression | +| P1R-14 | pending | reference generator | Run stored reference displacement regression using accepted Phase 1-compatible S4 cases. | P1R-13 | At least one automated CSV displacement regression | | P1R-15 | pending | evaluator | Independent Phase 1 evaluator closeout. | P1R-14 | Pass/fail report, synchronized PLAN/PROGRESS | ## Phase 1 Sprint Contract Rules @@ -131,9 +129,9 @@ Current reference state: - `quad_01.inp` contains `S4R`, `Part/Assembly/Instance`, `*Density`, and `NLGEOM=YES`; it is not a Phase 1 parser acceptance case as-is. - `references/quad_02.inp` and `references/quad_02_displacements.csv` have been added by the user as an S4 reference pair. - `quad_02.inp` uses `TYPE=S4`, but also includes `Part/Assembly/Instance`; this is a compatibility decision point, not automatic parser scope expansion. +- `references/quad_02_phase1.inp` is the accepted normalized Phase 1-compatible derivative input for the `quad_02` S4 reference pair. Required reference additions or decisions: -- Decide whether `quad_02.inp` is normalized into the current Phase 1 keyword subset or used to justify a dedicated Abaqus/CAE `Part/Assembly/Instance` parser sprint. - Add `*_reactions.csv` or explicitly use internal equilibrium tests for Phase 1 `RF` until Abaqus RF output is available. - Add more small cases until Phase 1 can pass one single-element case, one simple multi-element plate/shell case, and one curved shell benchmark. diff --git a/PROGRESS.md b/PROGRESS.md index a8fd64a..d687f0d 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -13,10 +13,40 @@ Every new agent session must read this file together with `PLAN.md` before plann - Do not remove history unless the user explicitly asks for archival cleanup. ## Current Status -Phase 1 has a new rebaseline phase definition in `phases/1-linear-static-mitc4-rebaseline`. Step 0 is complete and captured in `phases/1-linear-static-mitc4-rebaseline/step0-audit.md`. The old `phases/1-linear-static-mitc4` path is historical and superseded after the MITC4 formulation reset. P1-01 through P1-14 have an initial C++17 implementation, but it is no longer authoritative until each layer is revalidated against the revised paper-based `docs/MITC4_FORMULATION.md`. `quad_02` is now the stored S4 reference pair, but its `Part/Assembly/Instance` and `*Density` features remain a compatibility decision for rebaseline step 1. +Phase 1 has a new rebaseline phase definition in `phases/1-linear-static-mitc4-rebaseline`. Steps 0 and 1 are complete. `quad_02_phase1.inp` is now the normalized Phase 1-compatible input path for the stored `quad_02` S4 reference pair, while the original `quad_02.inp` remains preserved unsupported provenance. The old `phases/1-linear-static-mitc4` path is historical and superseded after the MITC4 formulation reset. P1-01 through P1-14 have an initial C++17 implementation, but it is no longer authoritative until each layer is revalidated against the revised paper-based `docs/MITC4_FORMULATION.md`. ## Completed Work +### 2026-05-04 - P1R-01 quad_02 reference onboarding completed +Author: Codex + +Changed files: +- `references/quad_02_phase1.inp` +- `references/quad_02_notes.md` +- `references/README.md` +- `docs/ABAQUS_INPUT_SUBSET.md` +- `docs/VERIFICATION_PLAN.md` +- `tests/test_main.cpp` +- `phases/1-linear-static-mitc4-rebaseline/index.json` +- `PLAN.md` +- `PROGRESS.md` + +Summary: +- Preserved `references/quad_02.inp` and `references/quad_02_displacements.csv` unchanged as the original Abaqus/CAE S4 reference provenance. +- Added `references/quad_02_phase1.inp`, a normalized Phase 1-compatible derivative input that removes `Part/Assembly/Instance`, `*Density`, restart/output requests, and unsupported step metadata while preserving ids, connectivity, material, shell thickness, fixed boundary nodes, load node, and load magnitude. +- Added `references/quad_02_notes.md` with provenance, compatibility, unit-system, result mapping, tolerance, and RF limitation notes. +- Added tests proving the original `quad_02.inp` remains unsupported provenance, the normalized input parses into 121 nodes and 100 S4 elements, and `quad_02_displacements.csv` loads 121 node rows. +- Updated reference and parser documentation so the normalized file is the accepted `quad_02` path for future Phase 1 stored-reference regression. + +Verification: +- First ran `python scripts/validate_workspace.py` after adding tests; it failed as expected because `quad_02_phase1.inp` did not exist yet. +- After adding the normalized input and documentation, `python scripts/validate_workspace.py` configured CMake, built `fesa_core` and `fesa_tests`, and ran CTest successfully. +- CTest result: 1 test executable passed. + +Follow-up: +- Continue with P1R-02 core harness guardrails. +- Keep `RF` verified by internal full-vector equilibrium until a `*_reactions.csv` artifact is provided. + ### 2026-05-04 - P1R-00 rebaseline audit completed Author: Codex @@ -448,10 +478,10 @@ Verification: ## Known Blockers - No reaction-force reference artifact exists yet under `references/`. - The current initial `quad_01.inp` reference contains `S4R`, `Part/Assembly/Instance`, `*Density`, and `NLGEOM=YES`, so it is not a Phase 1 parser acceptance case as-is. -- `quad_02.inp` is a stored Abaqus `TYPE=S4` reference with matching displacement CSV, but it contains `Part/Assembly/Instance` and `*Density`; Step 1 must define a normalized-input or explicit parser-compatibility path before stored-reference regression. ## Current Risks - Implementation could start from the `quad_01` reference input without accounting for its unsupported Abaqus features. - Implementation could treat the old MITC4 kernel as authoritative even though it conflicts with the revised formulation contract. +- Future work could accidentally parse the original `quad_02.inp` instead of the normalized `quad_02_phase1.inp` before parser compatibility is explicitly expanded. - Reaction output may be wrong if full-space stiffness/load data is not preserved or reconstructed. - Large-model support may be weakened if any module narrows ids or sparse indices below int64. diff --git a/docs/ABAQUS_INPUT_SUBSET.md b/docs/ABAQUS_INPUT_SUBSET.md index 366e73a..423ccc9 100644 --- a/docs/ABAQUS_INPUT_SUBSET.md +++ b/docs/ABAQUS_INPUT_SUBSET.md @@ -44,6 +44,7 @@ FESA parser rules: - Abbreviated Abaqus keywords are not supported in Phase 1. Require exact keyword names after case normalization. - Include files through `INPUT=` are not supported in Phase 1. - Part/Assembly/Instance syntax is not supported in Phase 1 unless added by ADR. +- Normalized derivative inputs such as `references/quad_02_phase1.inp` may be used for Phase 1 parser and solver tests when the original stored Abaqus file contains unsupported Abaqus/CAE scaffolding. ## Stored Reference Inputs vs Supported Subset Files under `references/` are allowed to preserve the exact Abaqus input used to generate reference results, even when the file contains features outside the current Phase 1 parser subset. @@ -60,6 +61,7 @@ Current stored reference notes: - Its paired `references/quad_01_displacements.csv` is still valid as a stored displacement reference artifact for future compatibility and regression work. - `references/quad_02.inp` uses `TYPE=S4`, so it targets the Phase 1 MITC4 element formulation, and its paired `references/quad_02_displacements.csv` has the accepted displacement CSV shape. - `quad_02.inp` still uses Abaqus/CAE `Part`, `Assembly`, `Instance`, and `*Density`; it is therefore a stored S4 reference artifact and compatibility decision point, not automatic parser acceptance as-is. +- `references/quad_02_phase1.inp` is the normalized Phase 1-compatible derivative input for `quad_02`. It preserves node ids, element ids/connectivity, S4 element type, elastic material, shell thickness, fixed boundary nodes, load node, and concentrated load while removing `Part/Assembly/Instance`, `*Density`, restart/output request keywords, and unsupported step metadata. ## Labels and Names Rules: diff --git a/docs/VERIFICATION_PLAN.md b/docs/VERIFICATION_PLAN.md index 8d9da6a..b373ea2 100644 --- a/docs/VERIFICATION_PLAN.md +++ b/docs/VERIFICATION_PLAN.md @@ -50,6 +50,7 @@ references/ quad_01.inp quad_01_displacements.csv quad_02.inp + quad_02_phase1.inp quad_02_displacements.csv ``` @@ -160,12 +161,14 @@ Current initial case: |---|---|---| | `quad_01` | `quad_01.inp`, `quad_01_displacements.csv` | Abaqus/CAE Learning Edition 2024 input; 121 displacement rows; includes `S4R`, `Part/Assembly/Instance`, `*Density`, and `NLGEOM=YES`, which are outside the current Phase 1 parser/solver subset | | `quad_02` | `quad_02.inp`, `quad_02_displacements.csv` | Abaqus/CAE input; 121 displacement rows; uses `TYPE=S4` and `NLGEOM=NO`, but still includes `Part/Assembly/Instance` and `*Density`, so it must be normalized or handled by an explicit parser compatibility sprint before automated Phase 1 input acceptance | +| `quad_02_phase1` | `quad_02_phase1.inp`, `quad_02_displacements.csv`, `quad_02_notes.md` | Phase 1-compatible derivative input for `quad_02`; preserves ids, connectivity, material, thickness, boundary nodes, load node, and load magnitude while removing unsupported Abaqus/CAE scaffolding | Rules: - Original `.inp` files under `references/` should not be modified just to fit FESA Phase 1. - If a normalized Phase 1-compatible input is needed, add it as a separate file with a clear name and note its relationship to the original. - Unsupported features in stored reference inputs must be reported by compatibility checks, not silently accepted by parser tests. - A reference case may be useful for future compatibility even before it is executable by the current Phase 1 solver. +- `quad_02_phase1.inp` is the accepted normalized input path for the first `quad_02` Phase 1 S4 reference regression after the MITC4 rebuild and end-to-end workflow are complete. ## Tolerance Policy Use absolute and relative tolerance: diff --git a/phases/1-linear-static-mitc4-rebaseline/index.json b/phases/1-linear-static-mitc4-rebaseline/index.json index d2713ef..c952dd1 100644 --- a/phases/1-linear-static-mitc4-rebaseline/index.json +++ b/phases/1-linear-static-mitc4-rebaseline/index.json @@ -3,7 +3,7 @@ "phase": "1-linear-static-mitc4-rebaseline", "steps": [ { "step": 0, "name": "rebaseline-audit", "status": "completed" }, - { "step": 1, "name": "reference-onboarding", "status": "pending" }, + { "step": 1, "name": "reference-onboarding", "status": "completed" }, { "step": 2, "name": "core-harness-guardrails", "status": "pending" }, { "step": 3, "name": "parser-domain-subset", "status": "pending" }, { "step": 4, "name": "validation-singular-diagnostics", "status": "pending" }, diff --git a/references/README.md b/references/README.md index d4d51df..4fc9834 100644 --- a/references/README.md +++ b/references/README.md @@ -9,6 +9,11 @@ Abaqus is not run by the repository validation flow. Files here are treated as s | Case | Input | Result Artifact | Notes | |---|---|---|---| | `quad_01` | `quad_01.inp` | `quad_01_displacements.csv` | Abaqus/CAE Learning Edition 2024 source input; displacement CSV has 121 nodal rows | +| `quad_02` | `quad_02.inp` | `quad_02_displacements.csv` | Abaqus/CAE Learning Edition 2024 source input; `TYPE=S4`; displacement CSV has 121 nodal rows; original input remains unsupported provenance because it contains Abaqus/CAE scaffolding | +| `quad_02_phase1` | `quad_02_phase1.inp` | `quad_02_displacements.csv` | Normalized Phase 1 parser-compatible derivative of `quad_02.inp`; preserves ids, connectivity, material, shell thickness, fixed boundary set, and concentrated load | + +Case-specific notes: +- `quad_02_notes.md` ## Displacement CSV Format @@ -35,3 +40,5 @@ Mapping to FESA: Stored Abaqus inputs may contain features outside the current FESA Phase 1 parser subset. Preserve the original files and document unsupported features instead of editing them in place. `quad_01.inp` currently includes `TYPE=S4R`, `Part/Assembly/Instance`, `*Density`, and `NLGEOM=YES`. These are stored for reference provenance and future compatibility work; they are not Phase 1 parser acceptance requirements unless `docs/ABAQUS_INPUT_SUBSET.md` and `docs/ADR.md` are updated. + +`quad_02.inp` currently includes `TYPE=S4`, `Part/Assembly/Instance`, `*Density`, restart/output request keywords, and Abaqus/CAE step metadata. `quad_02_phase1.inp` is the accepted Phase 1-compatible derivative input. The original file must continue to be treated as stored provenance, not as parser acceptance. diff --git a/references/quad_02_notes.md b/references/quad_02_notes.md new file mode 100644 index 0000000..7638488 --- /dev/null +++ b/references/quad_02_notes.md @@ -0,0 +1,85 @@ +# quad_02 Reference Notes + +## Purpose +`quad_02` is the first stored Abaqus `TYPE=S4` reference pair intended for the Phase 1 MITC4 rebaseline path. + +The original Abaqus input remains preserved as provenance: +- `quad_02.inp` +- `quad_02_displacements.csv` + +The Phase 1 parser-compatible derivative input is: +- `quad_02_phase1.inp` + +## Provenance +- Source solver: Abaqus/CAE Learning Edition 2024, as recorded in `quad_02.inp`. +- Original job name: `quad_02`. +- Source model name: `Model-1`. +- Unit system: self-consistent source units. FESA does not enforce or convert units. + +## Compatibility +`quad_02.inp` uses `TYPE=S4`, which is the Phase 1 target mapped to FESA `MITC4`. + +The original file also contains Abaqus/CAE features outside the current Phase 1 parser subset: +- `*Part` +- `*Assembly` +- `*Instance` +- `*Density` +- output and restart request keywords + +These features remain unsupported in Phase 1 unless `docs/ABAQUS_INPUT_SUBSET.md` and ADRs are explicitly updated. Tests must continue to reject the original file as unsupported provenance. + +## Normalized Input +`quad_02_phase1.inp` is a derivative input created for Phase 1 parser and later solver regression work. + +It preserves: +- 121 node ids and coordinates. +- 100 `TYPE=S4` quadrilateral elements and connectivity. +- Elastic material values `E = 7.0e10`, `nu = 0.3`. +- Shell thickness `1.0`. +- Fixed boundary nodes from the original assembly-level boundary set. +- Concentrated load at node `2`, DOF `3`, magnitude `-100000.0`. + +It removes: +- Abaqus/CAE `Part/Assembly/Instance` scaffolding. +- `*Density`, because density is not used by Phase 1 linear static analysis. +- restart/output requests. +- step increment parameters and static time data not needed by the Phase 1 parser subset. + +## Result Mapping +`quad_02_displacements.csv` is an Abaqus-exported nodal displacement table with 121 rows. + +Required columns: +- `Node Label` +- `U-U1` +- `U-U2` +- `U-U3` +- `UR-UR1` +- `UR-UR2` +- `UR-UR3` + +It maps to FESA field output: + +```text +/results/steps/Step-1/frames/0/fieldOutputs/U +``` + +with component order: + +```text +UX, UY, UZ, RX, RY, RZ +``` + +## Initial Tolerance +Use the project default reference displacement starting point until case-specific calibration is justified: + +```text +abs_tol = 1.0e-12 +rel_tol = 1.0e-5 +reference_scale = 1.0 +``` + +Do not tune tolerances or drilling stiffness to make this single case pass. + +## Current Limitations +- `RF` has no paired Abaqus reaction CSV yet; verify `RF` by full-vector equilibrium until a `quad_02_reactions.csv` artifact is provided. +- Solver displacement comparison against this case must wait until the MITC4 rebuild and end-to-end linear static workflow are complete. diff --git a/references/quad_02_phase1.inp b/references/quad_02_phase1.inp new file mode 100644 index 0000000..57b7de5 --- /dev/null +++ b/references/quad_02_phase1.inp @@ -0,0 +1,252 @@ +** FESA Phase 1 normalized derivative of references/quad_02.inp +** Original source: Abaqus/CAE Learning Edition 2024, job quad_02. +** Paired displacement reference: references/quad_02_displacements.csv. +** Unit system: self-consistent source units; FESA does not enforce unit conversion. +** Normalization policy: +** - Preserve original node ids, element ids, S4 connectivity, material E/nu, +** shell thickness, fixed node set, concentrated load node, and load value. +** - Remove unsupported Abaqus/CAE scaffolding: Part, Assembly, Instance, +** Density, Restart, Output, and Step increment parameters. +*Node + 1, 10., 0., 0. + 2, 0., 0., 0. + 3, 0., -10., 0. + 4, 10., -10., 0. + 5, -10., 0., 0. + 6, -10., -10., 0. + 7, 0., 10., 0. + 8, -10., 10., 0. + 9, 10., 10., 0. + 10, 8., 0., 0. + 11, 6., 0., 0. + 12, 4., 0., 0. + 13, 2., 0., 0. + 14, 0., -2., 0. + 15, 0., -4., 0. + 16, 0., -6., 0. + 17, 0., -8., 0. + 18, 2., -10., 0. + 19, 4., -10., 0. + 20, 6., -10., 0. + 21, 8., -10., 0. + 22, 10., -8., 0. + 23, 10., -6., 0. + 24, 10., -4., 0. + 25, 10., -2., 0. + 26, -2., 0., 0. + 27, -4., 0., 0. + 28, -6., 0., 0. + 29, -8., 0., 0. + 30, -10., -2., 0. + 31, -10., -4., 0. + 32, -10., -6., 0. + 33, -10., -8., 0. + 34, -8., -10., 0. + 35, -6., -10., 0. + 36, -4., -10., 0. + 37, -2., -10., 0. + 38, 0., 2., 0. + 39, 0., 4., 0. + 40, 0., 6., 0. + 41, 0., 8., 0. + 42, -2., 10., 0. + 43, -4., 10., 0. + 44, -6., 10., 0. + 45, -8., 10., 0. + 46, -10., 8., 0. + 47, -10., 6., 0. + 48, -10., 4., 0. + 49, -10., 2., 0. + 50, 10., 2., 0. + 51, 10., 4., 0. + 52, 10., 6., 0. + 53, 10., 8., 0. + 54, 8., 10., 0. + 55, 6., 10., 0. + 56, 4., 10., 0. + 57, 2., 10., 0. + 58, 8., -2., 0. + 59, 6., -2., 0. + 60, 4., -2., 0. + 61, 2., -2., 0. + 62, 8., -4., 0. + 63, 6., -4., 0. + 64, 4., -4., 0. + 65, 2., -4., 0. + 66, 8., -6., 0. + 67, 6., -6., 0. + 68, 4., -6., 0. + 69, 2., -6., 0. + 70, 8., -8., 0. + 71, 6., -8., 0. + 72, 4., -8., 0. + 73, 2., -8., 0. + 74, -2., -2., 0. + 75, -4., -2., 0. + 76, -6., -2., 0. + 77, -8., -2., 0. + 78, -2., -4., 0. + 79, -4., -4., 0. + 80, -6., -4., 0. + 81, -8., -4., 0. + 82, -2., -6., 0. + 83, -4., -6., 0. + 84, -6., -6., 0. + 85, -8., -6., 0. + 86, -2., -8., 0. + 87, -4., -8., 0. + 88, -6., -8., 0. + 89, -8., -8., 0. + 90, -8., 2., 0. + 91, -6., 2., 0. + 92, -4., 2., 0. + 93, -2., 2., 0. + 94, -8., 4., 0. + 95, -6., 4., 0. + 96, -4., 4., 0. + 97, -2., 4., 0. + 98, -8., 6., 0. + 99, -6., 6., 0. + 100, -4., 6., 0. + 101, -2., 6., 0. + 102, -8., 8., 0. + 103, -6., 8., 0. + 104, -4., 8., 0. + 105, -2., 8., 0. + 106, 2., 2., 0. + 107, 4., 2., 0. + 108, 6., 2., 0. + 109, 8., 2., 0. + 110, 2., 4., 0. + 111, 4., 4., 0. + 112, 6., 4., 0. + 113, 8., 4., 0. + 114, 2., 6., 0. + 115, 4., 6., 0. + 116, 6., 6., 0. + 117, 8., 6., 0. + 118, 2., 8., 0. + 119, 4., 8., 0. + 120, 6., 8., 0. + 121, 8., 8., 0. +*Element, type=S4, elset=all_elements + 1, 1, 10, 58, 25 + 2, 10, 11, 59, 58 + 3, 11, 12, 60, 59 + 4, 12, 13, 61, 60 + 5, 13, 2, 14, 61 + 6, 25, 58, 62, 24 + 7, 58, 59, 63, 62 + 8, 59, 60, 64, 63 + 9, 60, 61, 65, 64 + 10, 61, 14, 15, 65 + 11, 24, 62, 66, 23 + 12, 62, 63, 67, 66 + 13, 63, 64, 68, 67 + 14, 64, 65, 69, 68 + 15, 65, 15, 16, 69 + 16, 23, 66, 70, 22 + 17, 66, 67, 71, 70 + 18, 67, 68, 72, 71 + 19, 68, 69, 73, 72 + 20, 69, 16, 17, 73 + 21, 22, 70, 21, 4 + 22, 70, 71, 20, 21 + 23, 71, 72, 19, 20 + 24, 72, 73, 18, 19 + 25, 73, 17, 3, 18 + 26, 2, 26, 74, 14 + 27, 26, 27, 75, 74 + 28, 27, 28, 76, 75 + 29, 28, 29, 77, 76 + 30, 29, 5, 30, 77 + 31, 14, 74, 78, 15 + 32, 74, 75, 79, 78 + 33, 75, 76, 80, 79 + 34, 76, 77, 81, 80 + 35, 77, 30, 31, 81 + 36, 15, 78, 82, 16 + 37, 78, 79, 83, 82 + 38, 79, 80, 84, 83 + 39, 80, 81, 85, 84 + 40, 81, 31, 32, 85 + 41, 16, 82, 86, 17 + 42, 82, 83, 87, 86 + 43, 83, 84, 88, 87 + 44, 84, 85, 89, 88 + 45, 85, 32, 33, 89 + 46, 17, 86, 37, 3 + 47, 86, 87, 36, 37 + 48, 87, 88, 35, 36 + 49, 88, 89, 34, 35 + 50, 89, 33, 6, 34 + 51, 5, 29, 90, 49 + 52, 29, 28, 91, 90 + 53, 28, 27, 92, 91 + 54, 27, 26, 93, 92 + 55, 26, 2, 38, 93 + 56, 49, 90, 94, 48 + 57, 90, 91, 95, 94 + 58, 91, 92, 96, 95 + 59, 92, 93, 97, 96 + 60, 93, 38, 39, 97 + 61, 48, 94, 98, 47 + 62, 94, 95, 99, 98 + 63, 95, 96, 100, 99 + 64, 96, 97, 101, 100 + 65, 97, 39, 40, 101 + 66, 47, 98, 102, 46 + 67, 98, 99, 103, 102 + 68, 99, 100, 104, 103 + 69, 100, 101, 105, 104 + 70, 101, 40, 41, 105 + 71, 46, 102, 45, 8 + 72, 102, 103, 44, 45 + 73, 103, 104, 43, 44 + 74, 104, 105, 42, 43 + 75, 105, 41, 7, 42 + 76, 2, 13, 106, 38 + 77, 13, 12, 107, 106 + 78, 12, 11, 108, 107 + 79, 11, 10, 109, 108 + 80, 10, 1, 50, 109 + 81, 38, 106, 110, 39 + 82, 106, 107, 111, 110 + 83, 107, 108, 112, 111 + 84, 108, 109, 113, 112 + 85, 109, 50, 51, 113 + 86, 39, 110, 114, 40 + 87, 110, 111, 115, 114 + 88, 111, 112, 116, 115 + 89, 112, 113, 117, 116 + 90, 113, 51, 52, 117 + 91, 40, 114, 118, 41 + 92, 114, 115, 119, 118 + 93, 115, 116, 120, 119 + 94, 116, 117, 121, 120 + 95, 117, 52, 53, 121 + 96, 41, 118, 57, 7 + 97, 118, 119, 56, 57 + 98, 119, 120, 55, 56 + 99, 120, 121, 54, 55 +100, 121, 53, 9, 54 +*Elset, elset=all_elements, generate +1, 100, 1 +*Nset, nset=fixed_boundary +1, 3, 4, 5, 6, 7, 8, 9, 18, 19, 20, 21, 22, 23, 24, 25 +30, 31, 32, 33, 34, 35, 36, 37, 42, 43, 44, 45, 46, 47, 48, 49 +50, 51, 52, 53, 54, 55, 56, 57 +*Nset, nset=load_node +2 +*Material, name=material_1 +*Elastic +7.0e10, 0.3 +*Shell Section, elset=all_elements, material=material_1 +1.0 +*Boundary +fixed_boundary, 1, 6, 0.0 +*Step, name=Step-1 +*Static +*Cload +load_node, 3, -100000.0 +*End Step diff --git a/tests/test_main.cpp b/tests/test_main.cpp index e532e01..a05ae39 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -150,6 +150,26 @@ FESA_TEST(quad01_reference_input_remains_unsupported) { fesa::containsDiagnostic(parsed.diagnostics, "FESA-PARSE-UNSUPPORTED-ELEMENT")); } +FESA_TEST(quad02_original_reference_input_remains_unsupported) { + fesa::AbaqusInputParser parser; + auto parsed = parser.parseFile(sourceRoot() + "/references/quad_02.inp"); + FESA_CHECK(!parsed.ok()); + FESA_CHECK(fesa::containsDiagnostic(parsed.diagnostics, "FESA-PARSE-UNSUPPORTED-KEYWORD")); +} + +FESA_TEST(quad02_phase1_normalized_input_uses_supported_subset) { + fesa::AbaqusInputParser parser; + auto parsed = parser.parseFile(sourceRoot() + "/references/quad_02_phase1.inp"); + FESA_CHECK(parsed.ok()); + FESA_CHECK(parsed.domain.nodes.size() == 121); + FESA_CHECK(parsed.domain.elements.size() == 100); + FESA_CHECK(parsed.domain.node_sets.at("fixed_boundary").node_ids.size() == 40); + FESA_CHECK(parsed.domain.node_sets.at("load_node").node_ids.size() == 1); + FESA_CHECK(parsed.domain.element_sets.at("all_elements").element_ids.size() == 100); + FESA_CHECK(parsed.domain.materials.at("material_1").elastic_modulus == 7.0e10); + FESA_CHECK(parsed.domain.shell_sections.front().thickness == 1.0); +} + FESA_TEST(domain_validation_reports_missing_property_and_targets) { fesa::Domain domain; domain.nodes[1] = {1, {0, 0, 0}}; @@ -223,6 +243,14 @@ FESA_TEST(displacement_csv_loader_accepts_quad01_format) { FESA_CHECK(table.rows.count(1) == 1); } +FESA_TEST(displacement_csv_loader_accepts_quad02_format) { + auto table = fesa::loadDisplacementCsv(sourceRoot() + "/references/quad_02_displacements.csv"); + FESA_CHECK(!fesa::hasError(table.diagnostics)); + FESA_CHECK(table.rows.size() == 121); + FESA_CHECK(table.rows.count(2) == 1); + FESA_CHECK(table.rows.at(2).values[2] < 0.0); +} + FESA_TEST(displacement_comparator_matches_by_node_id_not_row_order) { fesa::FieldOutput actual; actual.name = "U";