fix: add abaqus uel wrapper contract
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
- Phase directory: `phases/uel-3d-euler-beam`
|
- Phase directory: `phases/uel-3d-euler-beam`
|
||||||
- Current planned entry point: `python scripts/execute.py uel-3d-euler-beam`
|
- Current planned entry point: `python scripts/execute.py uel-3d-euler-beam`
|
||||||
- First pending action: correct Abaqus-facing `UEL` wrapper/interface mismatch before `step8` validation readiness
|
- First pending action: execute `step8` validation readiness using the corrected Abaqus-facing `UEL` wrapper/interface
|
||||||
|
|
||||||
## Planned Steps
|
## Planned Steps
|
||||||
|
|
||||||
@@ -46,4 +46,4 @@
|
|||||||
- Confirm exact first-scope beam assumptions in the requirements step.
|
- Confirm exact first-scope beam assumptions in the requirements step.
|
||||||
- Decide `PROPS`/`JPROPS` ordering and orientation-vector convention in the interface step.
|
- Decide `PROPS`/`JPROPS` ordering and orientation-vector convention in the interface step.
|
||||||
- Decide exact no-Abaqus Fortran source and test file layout in the reference model step.
|
- Decide exact no-Abaqus Fortran source and test file layout in the reference model step.
|
||||||
- Add a top-level Abaqus-callable `SUBROUTINE UEL(...)` wrapper and correct the `VARIABLES`/`NSVARS` policy before external Abaqus validation readiness.
|
- External Abaqus validation artifacts still need to be supplied by the user before solver-result comparison.
|
||||||
|
|||||||
+16
-6
@@ -5,8 +5,8 @@
|
|||||||
- Active objective: 3D Euler-Bernoulli beam Abaqus/Standard `UEL`
|
- Active objective: 3D Euler-Bernoulli beam Abaqus/Standard `UEL`
|
||||||
- Active phase: `phases/uel-3d-euler-beam`
|
- Active phase: `phases/uel-3d-euler-beam`
|
||||||
- Active owner: unassigned
|
- Active owner: unassigned
|
||||||
- Current status: completed ad hoc UEL ABI research correction note after step 7 implementation review
|
- Current status: completed Abaqus-facing UEL wrapper/interface correction after step 7 implementation review
|
||||||
- Next action: correct the Abaqus-facing UEL wrapper/interface mismatch before executing `phases/uel-3d-euler-beam/step8.md` validation-readiness step
|
- Next action: execute `phases/uel-3d-euler-beam/step8.md` validation-readiness step with corrected `VARIABLES=1` / `NSVARS>=1` contract
|
||||||
|
|
||||||
## Completed
|
## Completed
|
||||||
|
|
||||||
@@ -54,6 +54,11 @@
|
|||||||
- Confirmed current source has no top-level Abaqus-callable `SUBROUTINE UEL(...)` wrapper under `src/fortran`.
|
- Confirmed current source has no top-level Abaqus-callable `SUBROUTINE UEL(...)` wrapper under `src/fortran`.
|
||||||
- Confirmed `uel3deb_abi_static` is a no-Abaqus adapter, not the manual Abaqus UEL ABI.
|
- Confirmed `uel3deb_abi_static` is a no-Abaqus adapter, not the manual Abaqus UEL ABI.
|
||||||
- Identified a likely Abaqus input contract issue: documented `*USER ELEMENT, VARIABLES` must be greater than zero, so the current `NSVARS=0` / `VARIABLES=0` contract should be corrected before external Abaqus validation.
|
- Identified a likely Abaqus input contract issue: documented `*USER ELEMENT, VARIABLES` must be greater than zero, so the current `NSVARS=0` / `VARIABLES=0` contract should be corrected before external Abaqus validation.
|
||||||
|
- Completed Abaqus-facing UEL ABI correction.
|
||||||
|
- Added `src/fortran/uel_3d_euler_beam_uel.for` with top-level fixed-form `SUBROUTINE UEL(...)`, `ABA_PARAM.INC`, manual Abaqus array dimensions, adapter delegation, and fatal `XIT` path.
|
||||||
|
- Updated `uel3deb_abi_static` to accept `NSVARS>=1`, use explicit/manual-style array bounds, and validate `LFLAGS(1)` and `LFLAGS(4)`.
|
||||||
|
- Updated no-Abaqus tests and wrapper source-smoke tests for the corrected contract.
|
||||||
|
- Updated `docs/io-definitions/uel-3d-euler-beam.md`, `docs/reference-models/uel-3d-euler-beam.md`, and `docs/corrections/uel-3d-euler-beam-uel-abi-correction.md`.
|
||||||
|
|
||||||
## In Progress
|
## In Progress
|
||||||
|
|
||||||
@@ -65,17 +70,21 @@
|
|||||||
|
|
||||||
## Last Verification
|
## Last Verification
|
||||||
|
|
||||||
Latest verification after creating the UEL ABI research document:
|
Latest verification after correcting the Abaqus-facing UEL wrapper/interface:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m unittest discover -s scripts -p "test_*.py"
|
python -m unittest discover -s scripts -p "test_*.py"
|
||||||
|
python scripts/validate_reference_artifacts.py
|
||||||
|
python scripts/validate_fortran.py
|
||||||
python scripts/validate_workspace.py
|
python scripts/validate_workspace.py
|
||||||
git diff --check
|
git diff --check
|
||||||
```
|
```
|
||||||
|
|
||||||
Result: all passed.
|
Result: all passed.
|
||||||
- `python -m unittest discover -s scripts -p "test_*.py"`: 57 tests passed.
|
- `python -m unittest discover -s scripts -p "test_*.py"`: 60 tests passed.
|
||||||
- `python scripts/validate_workspace.py`: reference artifact validation succeeded; six Fortran manifest executables compiled and passed with Intel `ifx`; workspace validation succeeded.
|
- `python scripts/validate_reference_artifacts.py`: reference artifact metadata validation succeeded.
|
||||||
|
- `python scripts/validate_fortran.py`: six Fortran manifest executables compiled and passed with Intel `ifx`.
|
||||||
|
- `python scripts/validate_workspace.py`: reference validation and Fortran validation succeeded.
|
||||||
- `git diff --check`: passed with line-ending warnings only.
|
- `git diff --check`: passed with line-ending warnings only.
|
||||||
|
|
||||||
Previous verification after completing step 7 Fortran implementation:
|
Previous verification after completing step 7 Fortran implementation:
|
||||||
@@ -98,5 +107,6 @@ Result: all passed.
|
|||||||
|
|
||||||
- Read `AGENTS.md`, `PLAN.md`, `PROGRESS.md`, and `WORKNOTE.md`.
|
- Read `AGENTS.md`, `PLAN.md`, `PROGRESS.md`, and `WORKNOTE.md`.
|
||||||
- Confirm no other owner is active in this file.
|
- Confirm no other owner is active in this file.
|
||||||
- Correct the Abaqus-facing `UEL` wrapper/interface mismatch before `phases/uel-3d-euler-beam/step8.md`.
|
- Proceed to `phases/uel-3d-euler-beam/step8.md`.
|
||||||
|
- Use `VARIABLES=1` in external Abaqus `*USER ELEMENT` examples; the adapter now requires `NSVARS>=1`.
|
||||||
- Update this file when step status changes or before handing off.
|
- Update this file when step status changes or before handing off.
|
||||||
|
|||||||
@@ -17,3 +17,5 @@
|
|||||||
- 같은 조사에서 현재 `src/fortran`에는 Abaqus가 직접 호출할 top-level external `SUBROUTINE UEL(...)` wrapper가 없고, `uel3deb_abi_static`은 no-Abaqus adapter일 뿐임을 확인했다. 다음 구현 보정에서는 manual signature와 `ABA_PARAM.INC` include를 보존하는 wrapper가 필요하다.
|
- 같은 조사에서 현재 `src/fortran`에는 Abaqus가 직접 호출할 top-level external `SUBROUTINE UEL(...)` wrapper가 없고, `uel3deb_abi_static`은 no-Abaqus adapter일 뿐임을 확인했다. 다음 구현 보정에서는 manual signature와 `ABA_PARAM.INC` include를 보존하는 wrapper가 필요하다.
|
||||||
- `docs/io-definitions/uel-3d-euler-beam.md`의 `VARIABLES=0`/`NSVARS=0` 정책은 Abaqus `*USER ELEMENT` 문서의 `VARIABLES` 값이 0보다 커야 한다는 규칙과 충돌할 가능성이 있다. 실제 Abaqus-facing 계약은 `VARIABLES=1` 이상 또는 target-version 근거가 있는 예외로 보정해야 한다.
|
- `docs/io-definitions/uel-3d-euler-beam.md`의 `VARIABLES=0`/`NSVARS=0` 정책은 Abaqus `*USER ELEMENT` 문서의 `VARIABLES` 값이 0보다 커야 한다는 규칙과 충돌할 가능성이 있다. 실제 Abaqus-facing 계약은 `VARIABLES=1` 이상 또는 target-version 근거가 있는 예외로 보정해야 한다.
|
||||||
- PowerShell에서 `git add ... && git status --short`를 실행하면 이 환경에서는 `&&`가 statement separator로 인식되지 않아 실패한다. 명령은 분리해서 실행한다.
|
- PowerShell에서 `git add ... && git status --short`를 실행하면 이 환경에서는 `&&`가 statement separator로 인식되지 않아 실패한다. 명령은 분리해서 실행한다.
|
||||||
|
- 2026-06-12 UEL ABI correction에서 TDD guard는 production file basename token을 `tests/` 아래 테스트 파일명에서 찾는다. `scripts/test_uel_3d_euler_beam_uel.py`만으로는 `src/fortran/uel_3d_euler_beam_uel.for` 변경이 차단되어, `tests/test_uel_3d_euler_beam_uel.py` shim을 함께 추가했다.
|
||||||
|
- `tests/fortran/uel_3d_euler_beam/test_invalid_inputs.f90`의 helper 인자 순서를 바꿀 때 `NDLOAD` 케이스가 `lflag3=0`으로 들어가 `E016`보다 `E015`가 먼저 발생했다. negative test는 목표 조건 외의 request flag를 모두 유효값으로 유지해야 한다.
|
||||||
|
|||||||
@@ -3,10 +3,14 @@
|
|||||||
## Metadata
|
## Metadata
|
||||||
- feature_id: abaqus-uel-subroutines
|
- feature_id: abaqus-uel-subroutines
|
||||||
- related_feature: `uel-3d-euler-beam`
|
- related_feature: `uel-3d-euler-beam`
|
||||||
- status: ready-for-interface-correction
|
- status: implemented-follow-up
|
||||||
- owner_agent: research-agent
|
- owner_agent: research-agent
|
||||||
- date: 2026-06-12
|
- date: 2026-06-12
|
||||||
|
|
||||||
|
## Follow-up Status
|
||||||
|
|
||||||
|
The findings below captured the pre-correction state after the initial step 7 implementation. The follow-up correction in `docs/corrections/uel-3d-euler-beam-uel-abi-correction.md` adds the missing Abaqus-callable wrapper, changes the Abaqus-facing state-variable policy to `NSVARS>=1` / `VARIABLES=1`, and adds `LFLAGS(1)` and `LFLAGS(4)` validation.
|
||||||
|
|
||||||
## Research Questions
|
## Research Questions
|
||||||
- Abaqus/Standard가 실제로 호출하는 `UEL` subroutine의 positional ABI는 무엇인가?
|
- Abaqus/Standard가 실제로 호출하는 `UEL` subroutine의 positional ABI는 무엇인가?
|
||||||
- `RHS`, `AMATRX`, `SVARS`, `ENERGY`, `PNEWDT`, `LFLAGS`의 update 책임은 무엇인가?
|
- `RHS`, `AMATRX`, `SVARS`, `ENERGY`, `PNEWDT`, `LFLAGS`의 update 책임은 무엇인가?
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
## Implementation Scope
|
## Implementation Scope
|
||||||
|
|
||||||
|
Post-step ABI correction note: the original step 7 implementation deliberately deferred the fixed-form Abaqus `UEL` wrapper. The follow-up correction report `docs/corrections/uel-3d-euler-beam-uel-abi-correction.md` supersedes that deferred-wrapper status and records the added wrapper, `NSVARS>=1` policy, and `LFLAGS(1)/(4)` checks.
|
||||||
|
|
||||||
Production source added in this step:
|
Production source added in this step:
|
||||||
|
|
||||||
- `src/fortran/uel_3d_euler_beam_kernel.f90`
|
- `src/fortran/uel_3d_euler_beam_kernel.f90`
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# 3D Euler-Bernoulli Beam UEL ABI Correction Report
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
- feature_id: uel-3d-euler-beam
|
||||||
|
- source_failure_report: `docs/abaqus-uel-subroutines-research.md`
|
||||||
|
- source_implementation_report: `docs/build-test-reports/uel-3d-euler-beam-green.md`
|
||||||
|
- source_implementation_plan: N/A; correction follows the post-review research findings
|
||||||
|
- status: corrected-for-build-test
|
||||||
|
- owner_agent: correction-agent
|
||||||
|
- date: 2026-06-12
|
||||||
|
|
||||||
|
## Failure Triage
|
||||||
|
- classification: upstream-contract plus implementation defect
|
||||||
|
- first_failed_command: `python -m unittest scripts.test_uel_3d_euler_beam_uel`; `python scripts/validate_fortran.py`
|
||||||
|
- failed_target_or_test: missing Abaqus `UEL` wrapper; adapter rejected `NSVARS=1`
|
||||||
|
- evidence_tail: wrapper source-smoke failed because `src/fortran/uel_3d_euler_beam_uel.for` was missing; Fortran ABI test failed with `actual=6 expected=0` for a valid `NSVARS=1` static call
|
||||||
|
- triage_decision: implementation-owned correction allowed after research clarified the Abaqus manual ABI
|
||||||
|
|
||||||
|
## Root Cause Summary
|
||||||
|
- root_cause_type: implementation boundary defect and stale interface policy
|
||||||
|
- summary: the step 7 code implemented a testable kernel and no-Abaqus adapter, but did not expose the top-level Abaqus `SUBROUTINE UEL(...)`. The adapter also kept the pre-research `NSVARS=0` policy, conflicting with the documented `*USER ELEMENT, VARIABLES` requirement for a positive allocation.
|
||||||
|
- why_minimal_fix_is_allowed: the correction preserves the existing kernel formulation and only fixes the Abaqus-facing call boundary, state-variable allocation check, and static-procedure `LFLAGS` validation.
|
||||||
|
|
||||||
|
## Correction Scope
|
||||||
|
|
||||||
|
| file | change_type | reason | in_scope |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `src/fortran/uel_3d_euler_beam_uel.for` | source | add fixed-form Abaqus `UEL` wrapper with manual signature, `ABA_PARAM.INC`, manual dimensions, adapter call, and fatal `XIT` path | true |
|
||||||
|
| `src/fortran/uel_3d_euler_beam_abi_adapter.f90` | source | accept `NSVARS>=1`, use explicit/manual-style array bounds, and validate `LFLAGS(1)` / `LFLAGS(4)` | true |
|
||||||
|
| `src/fortran/uel_3d_euler_beam_kernel.f90` | source | add status ids for unsupported `LFLAGS(1)` and `LFLAGS(4)` | true |
|
||||||
|
| `scripts/test_uel_3d_euler_beam_uel.py` | test | verify wrapper signature, include, dimensions, adapter call, and fatal path without requiring Abaqus include files | true |
|
||||||
|
| `tests/test_uel_3d_euler_beam_uel.py` | test | expose a related test path for the production-source TDD guard | true |
|
||||||
|
| `tests/fortran/uel_3d_euler_beam/test_abi_static.f90` | test | update valid adapter calls to `NSVARS=1` and explicit static `LFLAGS` values | true |
|
||||||
|
| `tests/fortran/uel_3d_euler_beam/test_invalid_inputs.f90` | test | add `NSVARS<1`, `LFLAGS(1)`, and `LFLAGS(4)` diagnostics | true |
|
||||||
|
| `tests/fortran/test_uel_3d_euler_beam_abi_adapter.f90` | test | update source-smoke adapter call to the corrected policy | true |
|
||||||
|
| `docs/io-definitions/uel-3d-euler-beam.md` | documentation | align current interface contract with the implemented Abaqus-facing policy | true |
|
||||||
|
| `docs/reference-models/uel-3d-euler-beam.md` | documentation | align test model and input-deck requirements with `VARIABLES=1` and wrapper source-smoke | true |
|
||||||
|
|
||||||
|
Excluded files:
|
||||||
|
- reference artifacts: unchanged
|
||||||
|
- tolerances: unchanged
|
||||||
|
- formulation matrix/residual equations: unchanged
|
||||||
|
|
||||||
|
## Verification Evidence
|
||||||
|
|
||||||
|
| order | command | exit_code | result | evidence |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| 1 | `python -m unittest scripts.test_uel_3d_euler_beam_uel` before implementation | 1 | RED | failed because `src/fortran/uel_3d_euler_beam_uel.for` did not exist |
|
||||||
|
| 2 | `python scripts/validate_fortran.py` before implementation | 1 | RED | `uel_3d_euler_beam_abi_static` failed because `NSVARS=1` returned `UEL3DEB_E006_NSVARS` |
|
||||||
|
| 3 | `python -m unittest scripts.test_uel_3d_euler_beam_uel` after implementation | 0 | pass | wrapper source-smoke passed |
|
||||||
|
| 4 | `python scripts/validate_fortran.py` after implementation | 0 | pass | all six no-Abaqus Fortran manifest executables compiled and passed with Intel `ifx` |
|
||||||
|
| 5 | `python -m unittest discover -s scripts -p "test_*.py"` | 0 | pass | 60 Python harness/source-smoke tests passed |
|
||||||
|
| 6 | `python scripts/validate_workspace.py` | 0 | pass | reference artifact metadata validation and Fortran validation succeeded |
|
||||||
|
| 7 | `git diff --check` | 0 | pass | no whitespace errors; line-ending warnings only |
|
||||||
|
|
||||||
|
## Traceability
|
||||||
|
|
||||||
|
| requirement_or_finding | corrected_file | acceptance_criterion |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| C-UEL-001 / C-UEL-002 | `src/fortran/uel_3d_euler_beam_uel.for` | top-level external `SUBROUTINE UEL(...)` exists with manual ABI arguments |
|
||||||
|
| C-UEL-003 | `src/fortran/uel_3d_euler_beam_uel.for`, `src/fortran/uel_3d_euler_beam_abi_adapter.f90` | Abaqus-facing boundary uses manual dimensions; adapter remains testable |
|
||||||
|
| C-UEL-004 | `src/fortran/uel_3d_euler_beam_abi_adapter.f90`, `docs/io-definitions/uel-3d-euler-beam.md` | valid static adapter calls use `NSVARS=1`; `NSVARS<1` returns `UEL3DEB_E006_NSVARS` |
|
||||||
|
| C-UEL-005 | `src/fortran/uel_3d_euler_beam_abi_adapter.f90` | unsupported `LFLAGS(1)` and `LFLAGS(4)` return dedicated diagnostics |
|
||||||
|
|
||||||
|
## Handoff Recommendation
|
||||||
|
|
||||||
|
| target_agent | reason | required_input |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Build/Test Executor Agent | run full workspace validation after correction | this report and command evidence |
|
||||||
|
| Reference Verification Agent | update external model expectations to `VARIABLES=1` before user-generated Abaqus artifacts are prepared | corrected I/O and reference-model documents |
|
||||||
|
| Physics Evaluation Agent | no formulation behavior changed; external CSV physics checks remain pending | future user-provided reference bundles |
|
||||||
|
|
||||||
|
## Stop Condition
|
||||||
|
- repeated_failure: false
|
||||||
|
- upstream_ambiguity: false
|
||||||
|
- reference_artifact_gap: true
|
||||||
|
- environment_blocker: false
|
||||||
|
- next_required_decision: user must still provide external Abaqus artifacts before solver-result validation can complete
|
||||||
@@ -54,7 +54,7 @@ The wrapper must keep `aba_param.inc` / `ABA_PARAM.INC` as an Abaqus/Standard in
|
|||||||
| `MCRD` | `>= 3` | read only `COORDS(1:3,1:2)` |
|
| `MCRD` | `>= 3` | read only `COORDS(1:3,1:2)` |
|
||||||
| `NPROPS` | `9` | reject anything else |
|
| `NPROPS` | `9` | reject anything else |
|
||||||
| `NJPROP` | `0` | first scope uses no integer properties |
|
| `NJPROP` | `0` | first scope uses no integer properties |
|
||||||
| `NSVARS` | `0` | first scope stores no persistent state |
|
| `NSVARS` | `>= 1` | Abaqus `*USER ELEMENT` state-variable allocation must be positive; first scope leaves allocated `SVARS` entries unchanged |
|
||||||
| `NRHS` | `1` | reject multi-RHS procedures |
|
| `NRHS` | `1` | reject multi-RHS procedures |
|
||||||
| `MLVARX` | `>= 12` | required for `RHS(1:12,1)` and `DU(1:12,1)` addressing |
|
| `MLVARX` | `>= 12` | required for `RHS(1:12,1)` and `DU(1:12,1)` addressing |
|
||||||
| `NDLOAD` | `0` | element-generated distributed loads are unsupported |
|
| `NDLOAD` | `0` | element-generated distributed loads are unsupported |
|
||||||
@@ -137,7 +137,7 @@ The reference model plan should use this `.inp` subset.
|
|||||||
| `*ELEMENT` | supported | `TYPE=U1` or the approved user element type, optional `ELSET` | two-node UEL connectivity | connectivity order defines local axis 1 |
|
| `*ELEMENT` | supported | `TYPE=U1` or the approved user element type, optional `ELSET` | two-node UEL connectivity | connectivity order defines local axis 1 |
|
||||||
| `*ELSET` | supported | `ELSET` | element set | needed for `*UEL PROPERTY` |
|
| `*ELSET` | supported | `ELSET` | element set | needed for `*UEL PROPERTY` |
|
||||||
| `*NSET` | supported | `NSET` | node set | recommended for BC/load/output selection |
|
| `*NSET` | supported | `NSET` | node set | recommended for BC/load/output selection |
|
||||||
| `*USER ELEMENT` | supported | `TYPE=U1`, `NODES=2`, `COORDINATES=3`, `PROPERTIES=9`, `VARIABLES=0` | UEL declaration | omit `UNSYMM`; omit `I PROPERTIES` |
|
| `*USER ELEMENT` | supported | `TYPE=U1`, `NODES=2`, `COORDINATES=3`, `PROPERTIES=9`, `VARIABLES=1` | UEL declaration | omit `UNSYMM`; omit `I PROPERTIES`; `SVARS(1)` is unused |
|
||||||
| `*UEL PROPERTY` | supported | `ELSET` | real property assignment | data order is `PROPS(1:9)` |
|
| `*UEL PROPERTY` | supported | `ELSET` | real property assignment | data order is `PROPS(1:9)` |
|
||||||
| `*BOUNDARY` | supported | standard nodal DOF constraints | essential boundary conditions | DOFs 1-6 allowed |
|
| `*BOUNDARY` | supported | standard nodal DOF constraints | essential boundary conditions | DOFs 1-6 allowed |
|
||||||
| `*CLOAD` | supported | standard nodal concentrated load | external nodal loads/moments | loads are assembled by Abaqus outside UEL |
|
| `*CLOAD` | supported | standard nodal concentrated load | external nodal loads/moments | loads are assembled by Abaqus outside UEL |
|
||||||
@@ -161,7 +161,7 @@ Unsupported in first scope:
|
|||||||
The reference input deck should declare the user element with this logical content:
|
The reference input deck should declare the user element with this logical content:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
*USER ELEMENT, TYPE=U1, NODES=2, COORDINATES=3, PROPERTIES=9, VARIABLES=0
|
*USER ELEMENT, TYPE=U1, NODES=2, COORDINATES=3, PROPERTIES=9, VARIABLES=1
|
||||||
1, 2, 3, 4, 5, 6
|
1, 2, 3, 4, 5, 6
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -183,11 +183,11 @@ Line breaks may follow Abaqus input formatting rules, but the logical property o
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `RHS(MLVARX,*)` | output | Initialize requested storage to zero every call; for supported residual requests, set `RHS(1:12,1) = -K_global*U(1:12)`. |
|
| `RHS(MLVARX,*)` | output | Initialize requested storage to zero every call; for supported residual requests, set `RHS(1:12,1) = -K_global*U(1:12)`. |
|
||||||
| `AMATRX(NDOFEL,NDOFEL)` | output | Initialize all `12x12` entries to zero every call; for supported stiffness requests, set all entries to `K_global`. |
|
| `AMATRX(NDOFEL,NDOFEL)` | output | Initialize all `12x12` entries to zero every call; for supported stiffness requests, set all entries to `K_global`. |
|
||||||
| `SVARS(*)` | input/output | unused; require `NSVARS=0`; do not store diagnostics in first scope. |
|
| `SVARS(*)` | input/output | unused; require `NSVARS>=1` for Abaqus keyword compatibility; do not store diagnostics in first scope. |
|
||||||
| `ENERGY(8)` | input/output | set `ENERGY(1:8)=0.0` every supported call; do not use as validation evidence in first scope. |
|
| `ENERGY(8)` | input/output | set `ENERGY(1:8)=0.0` every supported call; do not use as validation evidence in first scope. |
|
||||||
| `NDOFEL` | input | must equal `12`. |
|
| `NDOFEL` | input | must equal `12`. |
|
||||||
| `NRHS` | input | must equal `1`. |
|
| `NRHS` | input | must equal `1`. |
|
||||||
| `NSVARS` | input | must equal `0`. |
|
| `NSVARS` | input | must be at least `1`. |
|
||||||
| `PROPS(*)` | input | must contain the 9 real values defined above. |
|
| `PROPS(*)` | input | must contain the 9 real values defined above. |
|
||||||
| `NPROPS` | input | must equal `9`. |
|
| `NPROPS` | input | must equal `9`. |
|
||||||
| `COORDS(MCRD,NNODE)` | input | read `COORDS(1:3,1)` and `COORDS(1:3,2)` as original global node coordinates. |
|
| `COORDS(MCRD,NNODE)` | input | read `COORDS(1:3,1)` and `COORDS(1:3,2)` as original global node coordinates. |
|
||||||
@@ -218,6 +218,8 @@ The first-scope wrapper supports only small-displacement static calls:
|
|||||||
|
|
||||||
- require `LFLAGS(2)=0`
|
- require `LFLAGS(2)=0`
|
||||||
- support `LFLAGS(3)=1`, `2`, or `5`
|
- support `LFLAGS(3)=1`, `2`, or `5`
|
||||||
|
- require `LFLAGS(1)=1` or `2` for static procedure calls
|
||||||
|
- require `LFLAGS(4)=0` for general-step behavior, not perturbation-only output
|
||||||
- require `NRHS=1`
|
- require `NRHS=1`
|
||||||
|
|
||||||
Contribution rules:
|
Contribution rules:
|
||||||
@@ -242,7 +244,7 @@ Invalid input must be caught before matrix assembly. The implementation may choo
|
|||||||
| `UEL3DEB-E003` | `MCRD < 3` | fatal missing 3D coordinates |
|
| `UEL3DEB-E003` | `MCRD < 3` | fatal missing 3D coordinates |
|
||||||
| `UEL3DEB-E004` | `NPROPS /= 9` | fatal wrong real property count |
|
| `UEL3DEB-E004` | `NPROPS /= 9` | fatal wrong real property count |
|
||||||
| `UEL3DEB-E005` | `NJPROP /= 0` | fatal unsupported integer properties |
|
| `UEL3DEB-E005` | `NJPROP /= 0` | fatal unsupported integer properties |
|
||||||
| `UEL3DEB-E006` | `NSVARS /= 0` | fatal unsupported state variables |
|
| `UEL3DEB-E006` | `NSVARS < 1` | fatal missing Abaqus state-variable allocation |
|
||||||
| `UEL3DEB-E007` | `NRHS /= 1` | fatal unsupported RHS count |
|
| `UEL3DEB-E007` | `NRHS /= 1` | fatal unsupported RHS count |
|
||||||
| `UEL3DEB-E008` | `MLVARX < 12` | fatal invalid RHS/DU leading dimension |
|
| `UEL3DEB-E008` | `MLVARX < 12` | fatal invalid RHS/DU leading dimension |
|
||||||
| `UEL3DEB-E009` | any required coordinate, `U`, or `PROPS` value is NaN or infinite | fatal nonfinite input |
|
| `UEL3DEB-E009` | any required coordinate, `U`, or `PROPS` value is NaN or infinite | fatal nonfinite input |
|
||||||
@@ -253,6 +255,8 @@ Invalid input must be caught before matrix assembly. The implementation may choo
|
|||||||
| `UEL3DEB-E014` | `LFLAGS(2) /= 0` | fatal unsupported large-displacement or non-small-displacement request |
|
| `UEL3DEB-E014` | `LFLAGS(2) /= 0` | fatal unsupported large-displacement or non-small-displacement request |
|
||||||
| `UEL3DEB-E015` | unsupported `LFLAGS(3)` | fatal unsupported contribution request |
|
| `UEL3DEB-E015` | unsupported `LFLAGS(3)` | fatal unsupported contribution request |
|
||||||
| `UEL3DEB-E016` | `NDLOAD /= 0` | fatal unsupported element load input |
|
| `UEL3DEB-E016` | `NDLOAD /= 0` | fatal unsupported element load input |
|
||||||
|
| `UEL3DEB-E017` | `LFLAGS(1)` is not `1` or `2` | fatal unsupported non-static procedure request |
|
||||||
|
| `UEL3DEB-E018` | `LFLAGS(4) /= 0` | fatal unsupported perturbation-output request |
|
||||||
|
|
||||||
For valid supported calls, the wrapper should set deterministic outputs for the requested contribution and should not modify `PNEWDT`.
|
For valid supported calls, the wrapper should set deterministic outputs for the requested contribution and should not modify `PNEWDT`.
|
||||||
|
|
||||||
@@ -358,7 +362,7 @@ Each external reference model must include metadata fields sufficient for `scrip
|
|||||||
### Reference Model Agent
|
### Reference Model Agent
|
||||||
|
|
||||||
- Use the keyword subset and property order in this document for `model.inp` examples.
|
- Use the keyword subset and property order in this document for `model.inp` examples.
|
||||||
- Include no-Abaqus tests for exact `PROPS(1:9)` mapping, `NJPROP=0`, `NSVARS=0`, `NDOFEL=12`, `NNODE=2`, and active DOF order.
|
- Include no-Abaqus tests for exact `PROPS(1:9)` mapping, `NJPROP=0`, `NSVARS>=1`, `NDOFEL=12`, `NNODE=2`, and active DOF order.
|
||||||
- Include negative tests for every `UEL3DEB-E###` validation rule that is practical in the no-Abaqus harness.
|
- Include negative tests for every `UEL3DEB-E###` validation rule that is practical in the no-Abaqus harness.
|
||||||
- Define benchmark-specific CSV filenames and near-zero absolute reaction tolerances.
|
- Define benchmark-specific CSV filenames and near-zero absolute reaction tolerances.
|
||||||
- Keep external artifact generation outside this repository.
|
- Keep external artifact generation outside this repository.
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Production source paths planned for later steps:
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `src/fortran/uel_3d_euler_beam_kernel.f90` | pure/testable beam geometry, local stiffness, transform, residual, and validation logic | compiled by all no-Abaqus kernel and ABI adapter tests |
|
| `src/fortran/uel_3d_euler_beam_kernel.f90` | pure/testable beam geometry, local stiffness, transform, residual, and validation logic | compiled by all no-Abaqus kernel and ABI adapter tests |
|
||||||
| `src/fortran/uel_3d_euler_beam_abi_adapter.f90` | Abaqus-array adapter logic without the literal Abaqus `UEL` entry point | compiled by no-Abaqus ABI mapping tests |
|
| `src/fortran/uel_3d_euler_beam_abi_adapter.f90` | Abaqus-array adapter logic without the literal Abaqus `UEL` entry point | compiled by no-Abaqus ABI mapping tests |
|
||||||
| `src/fortran/uel_3d_euler_beam_uel.for` | thin Abaqus/Standard fixed-form `UEL` wrapper preserving the manual signature and `ABA_PARAM.INC` include | not required for no-Abaqus compile in first RED tests; later wrapper smoke can be added when an Abaqus-compatible include environment is available |
|
| `src/fortran/uel_3d_euler_beam_uel.for` | thin Abaqus/Standard fixed-form `UEL` wrapper preserving the manual signature and `ABA_PARAM.INC` include | checked by Python source-smoke because the file depends on Abaqus-provided include and `XIT` |
|
||||||
|
|
||||||
Planned test source paths for step 6:
|
Planned test source paths for step 6:
|
||||||
|
|
||||||
@@ -43,6 +43,7 @@ Planned test source paths for step 6:
|
|||||||
| `tests/fortran/uel_3d_euler_beam/test_kernel_transform_modes.f90` | transformation, symmetry, reversed node order, and rigid-body mode tests |
|
| `tests/fortran/uel_3d_euler_beam/test_kernel_transform_modes.f90` | transformation, symmetry, reversed node order, and rigid-body mode tests |
|
||||||
| `tests/fortran/uel_3d_euler_beam/test_abi_static.f90` | no-Abaqus ABI adapter tests for `RHS`, `AMATRX`, `ENERGY`, dimensions, and `LFLAGS` |
|
| `tests/fortran/uel_3d_euler_beam/test_abi_static.f90` | no-Abaqus ABI adapter tests for `RHS`, `AMATRX`, `ENERGY`, dimensions, and `LFLAGS` |
|
||||||
| `tests/fortran/uel_3d_euler_beam/test_invalid_inputs.f90` | validation diagnostics and unsupported-request tests |
|
| `tests/fortran/uel_3d_euler_beam/test_invalid_inputs.f90` | validation diagnostics and unsupported-request tests |
|
||||||
|
| `scripts/test_uel_3d_euler_beam_uel.py` | source-smoke contract for the fixed-form Abaqus `UEL` wrapper signature and dimensions |
|
||||||
|
|
||||||
Step 6 RED expectation:
|
Step 6 RED expectation:
|
||||||
|
|
||||||
@@ -123,10 +124,10 @@ Step 6 should create this planned manifest:
|
|||||||
| NOA-A-RHS-001 | `uel_3d_euler_beam_abi_static` | ABI/residual | verify `RHS(1:12,1)=-K_global*U(1:12)` for `LFLAGS(3)=1` and `5` | compile failure or wrong sign | REQ-009 |
|
| NOA-A-RHS-001 | `uel_3d_euler_beam_abi_static` | ABI/residual | verify `RHS(1:12,1)=-K_global*U(1:12)` for `LFLAGS(3)=1` and `5` | compile failure or wrong sign | REQ-009 |
|
||||||
| NOA-A-AMATRX-001 | `uel_3d_euler_beam_abi_static` | ABI/stiffness | verify `AMATRX=K_global` for `LFLAGS(3)=1` and `2` and zeroed matrix for residual-only requests | compile failure or mapping mismatch | REQ-003, REQ-004, REQ-008 |
|
| NOA-A-AMATRX-001 | `uel_3d_euler_beam_abi_static` | ABI/stiffness | verify `AMATRX=K_global` for `LFLAGS(3)=1` and `2` and zeroed matrix for residual-only requests | compile failure or mapping mismatch | REQ-003, REQ-004, REQ-008 |
|
||||||
| NOA-A-PROPS-001 | `uel_3d_euler_beam_abi_static` | ABI/property mapping | verify `PROPS(1:9)` maps to `E,G,A,Iy,Iz,J,a_ref_1,a_ref_2,a_ref_3` exactly | compile failure or property permutation mismatch | REQ-005, REQ-007 |
|
| NOA-A-PROPS-001 | `uel_3d_euler_beam_abi_static` | ABI/property mapping | verify `PROPS(1:9)` maps to `E,G,A,Iy,Iz,J,a_ref_1,a_ref_2,a_ref_3` exactly | compile failure or property permutation mismatch | REQ-005, REQ-007 |
|
||||||
| NOA-A-ENERGY-001 | `uel_3d_euler_beam_abi_static` | ABI/output policy | verify `ENERGY(1:8)=0.0`, `NSVARS=0`, and `PNEWDT` is not changed for valid supported calls | compile failure or output policy mismatch | REQ-010 |
|
| NOA-A-ENERGY-001 | `uel_3d_euler_beam_abi_static` | ABI/output policy | verify `ENERGY(1:8)=0.0`, `NSVARS>=1`, and `PNEWDT` is not changed for valid supported calls | compile failure or output policy mismatch | REQ-010 |
|
||||||
| NOA-I-SHAPE-001 | `uel_3d_euler_beam_invalid_inputs` | negative | verify diagnostics for `NDOFEL`, `NNODE`, `MCRD`, `NPROPS`, `NJPROP`, `NSVARS`, `NRHS`, `MLVARX` violations | compile failure or missing diagnostic | REQ-003, REQ-006 |
|
| NOA-I-SHAPE-001 | `uel_3d_euler_beam_invalid_inputs` | negative | verify diagnostics for `NDOFEL`, `NNODE`, `MCRD`, `NPROPS`, `NJPROP`, `NSVARS`, `NRHS`, `MLVARX` violations | compile failure or missing diagnostic | REQ-003, REQ-006 |
|
||||||
| NOA-I-PHYS-001 | `uel_3d_euler_beam_invalid_inputs` | negative | verify diagnostics for nonfinite coordinates/properties, nonpositive `E,G,A,Iy,Iz,J`, zero length, zero orientation, and near-parallel orientation | compile failure or missing diagnostic | REQ-006, REQ-007 |
|
| NOA-I-PHYS-001 | `uel_3d_euler_beam_invalid_inputs` | negative | verify diagnostics for nonfinite coordinates/properties, nonpositive `E,G,A,Iy,Iz,J`, zero length, zero orientation, and near-parallel orientation | compile failure or missing diagnostic | REQ-006, REQ-007 |
|
||||||
| NOA-I-LFLAGS-001 | `uel_3d_euler_beam_invalid_inputs` | negative | verify diagnostics for unsupported `LFLAGS(2)`, unsupported `LFLAGS(3)`, and `NDLOAD /= 0` | compile failure or missing diagnostic | REQ-010 |
|
| NOA-I-LFLAGS-001 | `uel_3d_euler_beam_invalid_inputs` | negative | verify diagnostics for unsupported `LFLAGS(1)`, unsupported `LFLAGS(2)`, unsupported `LFLAGS(3)`, unsupported `LFLAGS(4)`, and `NDLOAD /= 0` | compile failure or missing diagnostic | REQ-010 |
|
||||||
|
|
||||||
Default no-Abaqus tolerances:
|
Default no-Abaqus tolerances:
|
||||||
|
|
||||||
@@ -143,10 +144,11 @@ The production `UEL` wrapper itself should remain a thin Abaqus ABI entry point.
|
|||||||
|
|
||||||
The ABI adapter tests must verify:
|
The ABI adapter tests must verify:
|
||||||
|
|
||||||
- `NDOFEL=12`, `NNODE=2`, `MCRD>=3`, `NPROPS=9`, `NJPROP=0`, `NSVARS=0`, `NRHS=1`, and `MLVARX>=12`
|
- `NDOFEL=12`, `NNODE=2`, `MCRD>=3`, `NPROPS=9`, `NJPROP=0`, `NSVARS>=1`, `NRHS=1`, and `MLVARX>=12`
|
||||||
- `COORDS(1:3,1:2)` maps to `X1`, `X2`
|
- `COORDS(1:3,1:2)` maps to `X1`, `X2`
|
||||||
- `U(1:12)` maps to the global kernel vector without permutation
|
- `U(1:12)` maps to the global kernel vector without permutation
|
||||||
- `PROPS(1:9)` maps exactly to the interface contract
|
- `PROPS(1:9)` maps exactly to the interface contract
|
||||||
|
- `LFLAGS(1)=1|2`, `LFLAGS(2)=0`, `LFLAGS(3)=1|2|5`, and `LFLAGS(4)=0` select the supported static general-step path
|
||||||
- `LFLAGS(3)=1`, `2`, and `5` select the expected `AMATRX` and `RHS` outputs
|
- `LFLAGS(3)=1`, `2`, and `5` select the expected `AMATRX` and `RHS` outputs
|
||||||
- non-requested `AMATRX` or `RHS` storage is deterministically zeroed by the no-Abaqus adapter
|
- non-requested `AMATRX` or `RHS` storage is deterministically zeroed by the no-Abaqus adapter
|
||||||
- `ENERGY(1:8)` is zeroed and `SVARS` is unused
|
- `ENERGY(1:8)` is zeroed and `SVARS` is unused
|
||||||
@@ -252,7 +254,7 @@ Every external `model.inp` must stay within the supported keyword subset from `d
|
|||||||
- `*ELEMENT`
|
- `*ELEMENT`
|
||||||
- `*ELSET`
|
- `*ELSET`
|
||||||
- `*NSET`
|
- `*NSET`
|
||||||
- `*USER ELEMENT, TYPE=U1, NODES=2, COORDINATES=3, PROPERTIES=9, VARIABLES=0`
|
- `*USER ELEMENT, TYPE=U1, NODES=2, COORDINATES=3, PROPERTIES=9, VARIABLES=1`
|
||||||
- active DOF line: `1, 2, 3, 4, 5, 6`
|
- active DOF line: `1, 2, 3, 4, 5, 6`
|
||||||
- `*UEL PROPERTY, ELSET=<uel_element_set>` with data order `E,G,A,Iy,Iz,J,a_ref_1,a_ref_2,a_ref_3`
|
- `*UEL PROPERTY, ELSET=<uel_element_set>` with data order `E,G,A,Iy,Iz,J,a_ref_1,a_ref_2,a_ref_3`
|
||||||
- `*BOUNDARY`
|
- `*BOUNDARY`
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import re
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
WRAPPER = ROOT / "src" / "fortran" / "uel_3d_euler_beam_uel.for"
|
||||||
|
|
||||||
|
|
||||||
|
def normalized_source() -> str:
|
||||||
|
if not WRAPPER.exists():
|
||||||
|
raise AssertionError(f"missing Abaqus UEL wrapper: {WRAPPER}")
|
||||||
|
return re.sub(r"\s+", " ", WRAPPER.read_text(encoding="utf-8").upper())
|
||||||
|
|
||||||
|
|
||||||
|
class Uel3dEulerBeamWrapperContractTests(unittest.TestCase):
|
||||||
|
def test_wrapper_file_exists(self):
|
||||||
|
self.assertTrue(WRAPPER.exists(), f"missing Abaqus UEL wrapper: {WRAPPER}")
|
||||||
|
|
||||||
|
def test_wrapper_preserves_manual_uel_signature(self):
|
||||||
|
text = normalized_source()
|
||||||
|
|
||||||
|
self.assertIn("SUBROUTINE UEL(", text)
|
||||||
|
self.assertIn("INCLUDE 'ABA_PARAM.INC'", text)
|
||||||
|
for token in (
|
||||||
|
"RHS",
|
||||||
|
"AMATRX",
|
||||||
|
"SVARS",
|
||||||
|
"ENERGY",
|
||||||
|
"NDOFEL",
|
||||||
|
"NRHS",
|
||||||
|
"NSVARS",
|
||||||
|
"PROPS",
|
||||||
|
"NPROPS",
|
||||||
|
"COORDS",
|
||||||
|
"MCRD",
|
||||||
|
"NNODE",
|
||||||
|
"U",
|
||||||
|
"DU",
|
||||||
|
"V",
|
||||||
|
"A",
|
||||||
|
"JTYPE",
|
||||||
|
"TIME",
|
||||||
|
"DTIME",
|
||||||
|
"KSTEP",
|
||||||
|
"KINC",
|
||||||
|
"JELEM",
|
||||||
|
"PARAMS",
|
||||||
|
"NDLOAD",
|
||||||
|
"JDLTYP",
|
||||||
|
"ADLMAG",
|
||||||
|
"PREDEF",
|
||||||
|
"NPREDF",
|
||||||
|
"LFLAGS",
|
||||||
|
"MLVARX",
|
||||||
|
"DDLMAG",
|
||||||
|
"MDLOAD",
|
||||||
|
"PNEWDT",
|
||||||
|
"JPROPS",
|
||||||
|
"NJPROP",
|
||||||
|
"PERIOD",
|
||||||
|
):
|
||||||
|
self.assertRegex(text, rf"\b{token}\b")
|
||||||
|
|
||||||
|
signature = text.split("INCLUDE 'ABA_PARAM.INC'", 1)[0]
|
||||||
|
self.assertNotRegex(signature, r"\bSTATUS\b")
|
||||||
|
|
||||||
|
def test_wrapper_uses_abaqus_dimensions_and_thin_adapter_call(self):
|
||||||
|
text = normalized_source()
|
||||||
|
|
||||||
|
for shape in (
|
||||||
|
"RHS(MLVARX,*)",
|
||||||
|
"AMATRX(NDOFEL,NDOFEL)",
|
||||||
|
"SVARS(*)",
|
||||||
|
"ENERGY(8)",
|
||||||
|
"PROPS(*)",
|
||||||
|
"COORDS(MCRD,NNODE)",
|
||||||
|
"U(NDOFEL)",
|
||||||
|
"DU(MLVARX,*)",
|
||||||
|
"V(NDOFEL)",
|
||||||
|
"A(NDOFEL)",
|
||||||
|
"TIME(2)",
|
||||||
|
"PARAMS(*)",
|
||||||
|
"JDLTYP(MDLOAD,*)",
|
||||||
|
"ADLMAG(MDLOAD,*)",
|
||||||
|
"DDLMAG(MDLOAD,*)",
|
||||||
|
"PREDEF(2,NPREDF,NNODE)",
|
||||||
|
"LFLAGS(*)",
|
||||||
|
"JPROPS(*)",
|
||||||
|
):
|
||||||
|
self.assertIn(shape, text)
|
||||||
|
|
||||||
|
self.assertIn("USE UEL_3D_EULER_BEAM_ABI_ADAPTER", text)
|
||||||
|
self.assertIn("CALL UEL3DEB_ABI_STATIC", text)
|
||||||
|
self.assertIn("CALL XIT", text)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -7,6 +7,7 @@ module uel_3d_euler_beam_abi_adapter
|
|||||||
UEL3DEB_E006_NSVARS, UEL3DEB_E007_NRHS, UEL3DEB_E008_MLVARX, &
|
UEL3DEB_E006_NSVARS, UEL3DEB_E007_NRHS, UEL3DEB_E008_MLVARX, &
|
||||||
UEL3DEB_E009_NONFINITE, UEL3DEB_E014_LFLAGS2, &
|
UEL3DEB_E009_NONFINITE, UEL3DEB_E014_LFLAGS2, &
|
||||||
UEL3DEB_E015_LFLAGS3, UEL3DEB_E016_NDLOAD, &
|
UEL3DEB_E015_LFLAGS3, UEL3DEB_E016_NDLOAD, &
|
||||||
|
UEL3DEB_E017_LFLAGS1, UEL3DEB_E018_LFLAGS4, &
|
||||||
uel3deb_validate_kernel_inputs, uel3deb_global_stiffness
|
uel3deb_validate_kernel_inputs, uel3deb_global_stiffness
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
@@ -22,24 +23,24 @@ contains
|
|||||||
props, nprops, coords, mcrd, nnode, u, &
|
props, nprops, coords, mcrd, nnode, u, &
|
||||||
lflags, mlvarx, ndload, pnewdt, jprops, &
|
lflags, mlvarx, ndload, pnewdt, jprops, &
|
||||||
njprop, status)
|
njprop, status)
|
||||||
real(dp), intent(inout) :: rhs(:, :)
|
|
||||||
real(dp), intent(inout) :: amatrx(:, :)
|
|
||||||
real(dp), intent(inout) :: energy(:)
|
|
||||||
integer, intent(in) :: ndofel
|
integer, intent(in) :: ndofel
|
||||||
integer, intent(in) :: nrhs
|
integer, intent(in) :: nrhs
|
||||||
integer, intent(in) :: nsvars
|
integer, intent(in) :: nsvars
|
||||||
real(dp), intent(in) :: props(:)
|
|
||||||
integer, intent(in) :: nprops
|
integer, intent(in) :: nprops
|
||||||
real(dp), intent(in) :: coords(:, :)
|
|
||||||
integer, intent(in) :: mcrd
|
integer, intent(in) :: mcrd
|
||||||
integer, intent(in) :: nnode
|
integer, intent(in) :: nnode
|
||||||
real(dp), intent(in) :: u(:)
|
|
||||||
integer, intent(in) :: lflags(:)
|
|
||||||
integer, intent(in) :: mlvarx
|
integer, intent(in) :: mlvarx
|
||||||
integer, intent(in) :: ndload
|
integer, intent(in) :: ndload
|
||||||
real(dp), intent(inout) :: pnewdt
|
|
||||||
integer, intent(in) :: jprops(:)
|
|
||||||
integer, intent(in) :: njprop
|
integer, intent(in) :: njprop
|
||||||
|
real(dp), intent(inout) :: rhs(mlvarx, *)
|
||||||
|
real(dp), intent(inout) :: amatrx(ndofel, ndofel)
|
||||||
|
real(dp), intent(inout) :: energy(8)
|
||||||
|
real(dp), intent(in) :: props(*)
|
||||||
|
real(dp), intent(in) :: coords(mcrd, nnode)
|
||||||
|
real(dp), intent(in) :: u(ndofel)
|
||||||
|
integer, intent(in) :: lflags(*)
|
||||||
|
real(dp), intent(inout) :: pnewdt
|
||||||
|
integer, intent(in) :: jprops(*)
|
||||||
integer, intent(out) :: status
|
integer, intent(out) :: status
|
||||||
real(dp) :: coords3(3, 2)
|
real(dp) :: coords3(3, 2)
|
||||||
real(dp) :: props9(9)
|
real(dp) :: props9(9)
|
||||||
@@ -49,9 +50,9 @@ contains
|
|||||||
real(dp) :: residual(12)
|
real(dp) :: residual(12)
|
||||||
|
|
||||||
status = UEL3DEB_OK
|
status = UEL3DEB_OK
|
||||||
rhs = 0.0_dp
|
if (mlvarx > 0 .and. nrhs > 0) rhs(1:mlvarx, 1:nrhs) = 0.0_dp
|
||||||
amatrx = 0.0_dp
|
if (ndofel > 0) amatrx(1:ndofel, 1:ndofel) = 0.0_dp
|
||||||
energy = 0.0_dp
|
energy(1:8) = 0.0_dp
|
||||||
|
|
||||||
if (ndofel /= 12) then
|
if (ndofel /= 12) then
|
||||||
status = UEL3DEB_E001_NDOFEL
|
status = UEL3DEB_E001_NDOFEL
|
||||||
@@ -73,7 +74,7 @@ contains
|
|||||||
status = UEL3DEB_E005_NJPROP
|
status = UEL3DEB_E005_NJPROP
|
||||||
return
|
return
|
||||||
end if
|
end if
|
||||||
if (nsvars /= 0) then
|
if (nsvars < 1) then
|
||||||
status = UEL3DEB_E006_NSVARS
|
status = UEL3DEB_E006_NSVARS
|
||||||
return
|
return
|
||||||
end if
|
end if
|
||||||
@@ -85,6 +86,10 @@ contains
|
|||||||
status = UEL3DEB_E008_MLVARX
|
status = UEL3DEB_E008_MLVARX
|
||||||
return
|
return
|
||||||
end if
|
end if
|
||||||
|
if (.not. any(lflags(1) == [1, 2])) then
|
||||||
|
status = UEL3DEB_E017_LFLAGS1
|
||||||
|
return
|
||||||
|
end if
|
||||||
if (lflags(2) /= 0) then
|
if (lflags(2) /= 0) then
|
||||||
status = UEL3DEB_E014_LFLAGS2
|
status = UEL3DEB_E014_LFLAGS2
|
||||||
return
|
return
|
||||||
@@ -93,6 +98,10 @@ contains
|
|||||||
status = UEL3DEB_E015_LFLAGS3
|
status = UEL3DEB_E015_LFLAGS3
|
||||||
return
|
return
|
||||||
end if
|
end if
|
||||||
|
if (lflags(4) /= 0) then
|
||||||
|
status = UEL3DEB_E018_LFLAGS4
|
||||||
|
return
|
||||||
|
end if
|
||||||
if (ndload /= 0) then
|
if (ndload /= 0) then
|
||||||
status = UEL3DEB_E016_NDLOAD
|
status = UEL3DEB_E016_NDLOAD
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ module uel_3d_euler_beam_kernel
|
|||||||
integer, parameter, public :: UEL3DEB_E014_LFLAGS2 = 14
|
integer, parameter, public :: UEL3DEB_E014_LFLAGS2 = 14
|
||||||
integer, parameter, public :: UEL3DEB_E015_LFLAGS3 = 15
|
integer, parameter, public :: UEL3DEB_E015_LFLAGS3 = 15
|
||||||
integer, parameter, public :: UEL3DEB_E016_NDLOAD = 16
|
integer, parameter, public :: UEL3DEB_E016_NDLOAD = 16
|
||||||
|
integer, parameter, public :: UEL3DEB_E017_LFLAGS1 = 17
|
||||||
|
integer, parameter, public :: UEL3DEB_E018_LFLAGS4 = 18
|
||||||
|
|
||||||
public :: uel3deb_validate_kernel_inputs
|
public :: uel3deb_validate_kernel_inputs
|
||||||
public :: uel3deb_local_stiffness
|
public :: uel3deb_local_stiffness
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
SUBROUTINE UEL(RHS, AMATRX, SVARS, ENERGY, NDOFEL,
|
||||||
|
1 NRHS, NSVARS, PROPS, NPROPS, COORDS, MCRD, NNODE,
|
||||||
|
2 U, DU, V, A, JTYPE, TIME, DTIME, KSTEP, KINC, JELEM,
|
||||||
|
3 PARAMS, NDLOAD, JDLTYP, ADLMAG, PREDEF, NPREDF,
|
||||||
|
4 LFLAGS, MLVARX, DDLMAG, MDLOAD, PNEWDT, JPROPS,
|
||||||
|
5 NJPROP, PERIOD)
|
||||||
|
USE uel_3d_euler_beam_abi_adapter, ONLY:
|
||||||
|
1 uel3deb_abi_static
|
||||||
|
INCLUDE 'ABA_PARAM.INC'
|
||||||
|
DIMENSION RHS(MLVARX,*), AMATRX(NDOFEL,NDOFEL),
|
||||||
|
1 SVARS(*), ENERGY(8), PROPS(*), COORDS(MCRD,NNODE),
|
||||||
|
2 U(NDOFEL), DU(MLVARX,*), V(NDOFEL), A(NDOFEL),
|
||||||
|
3 TIME(2), PARAMS(*), JDLTYP(MDLOAD,*),
|
||||||
|
4 ADLMAG(MDLOAD,*), DDLMAG(MDLOAD,*),
|
||||||
|
5 PREDEF(2,NPREDF,NNODE), LFLAGS(*), JPROPS(*)
|
||||||
|
INTEGER STATUS
|
||||||
|
|
||||||
|
CALL uel3deb_abi_static(RHS, AMATRX, ENERGY, NDOFEL,
|
||||||
|
1 NRHS, NSVARS, PROPS, NPROPS, COORDS, MCRD, NNODE,
|
||||||
|
2 U, LFLAGS, MLVARX, NDLOAD, PNEWDT, JPROPS, NJPROP,
|
||||||
|
3 STATUS)
|
||||||
|
|
||||||
|
IF (STATUS .NE. 0) THEN
|
||||||
|
WRITE(7,*) 'UEL3DEB fatal status=', STATUS,
|
||||||
|
1 ' JELEM=', JELEM, ' KSTEP=', KSTEP,
|
||||||
|
2 ' KINC=', KINC
|
||||||
|
CALL XIT
|
||||||
|
END IF
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
END
|
||||||
@@ -22,10 +22,12 @@ program test_uel_3d_euler_beam_abi_adapter
|
|||||||
u = 0.0_dp
|
u = 0.0_dp
|
||||||
pnewdt = 1.0_dp
|
pnewdt = 1.0_dp
|
||||||
lflags = 0
|
lflags = 0
|
||||||
|
lflags(1) = 1
|
||||||
lflags(3) = 2
|
lflags(3) = 2
|
||||||
|
lflags(4) = 0
|
||||||
jprops = 0
|
jprops = 0
|
||||||
|
|
||||||
call uel3deb_abi_static(rhs, amatrx, energy, 12, 1, 0, props, 9, coords, &
|
call uel3deb_abi_static(rhs, amatrx, energy, 12, 1, 1, props, 9, coords, &
|
||||||
3, 2, u, lflags, 12, 0, pnewdt, jprops, 0, status)
|
3, 2, u, lflags, 12, 0, pnewdt, jprops, 0, status)
|
||||||
call assert_equal_int(status, UEL3DEB_OK, 'abi adapter source smoke status')
|
call assert_equal_int(status, UEL3DEB_OK, 'abi adapter source smoke status')
|
||||||
call assert_matrix_symmetric(amatrx, tol_symmetry, 'abi adapter source smoke K')
|
call assert_matrix_symmetric(amatrx, tol_symmetry, 'abi adapter source smoke K')
|
||||||
|
|||||||
@@ -57,11 +57,13 @@ contains
|
|||||||
amatrx = 999.0_dp
|
amatrx = 999.0_dp
|
||||||
energy = 999.0_dp
|
energy = 999.0_dp
|
||||||
lflags = 0
|
lflags = 0
|
||||||
|
lflags(1) = 1
|
||||||
lflags(2) = 0
|
lflags(2) = 0
|
||||||
lflags(3) = lflags3
|
lflags(3) = lflags3
|
||||||
|
lflags(4) = 0
|
||||||
jprops = 0
|
jprops = 0
|
||||||
|
|
||||||
call uel3deb_abi_static(rhs, amatrx, energy, 12, 1, 0, props, 9, coords, &
|
call uel3deb_abi_static(rhs, amatrx, energy, 12, 1, 1, props, 9, coords, &
|
||||||
3, 2, u, lflags, 12, 0, pnewdt, jprops, 0, status)
|
3, 2, u, lflags, 12, 0, pnewdt, jprops, 0, status)
|
||||||
end subroutine call_adapter
|
end subroutine call_adapter
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ program test_invalid_inputs
|
|||||||
UEL3DEB_E010_NONPOSITIVE_PROPERTY, UEL3DEB_E011_ZERO_LENGTH, &
|
UEL3DEB_E010_NONPOSITIVE_PROPERTY, UEL3DEB_E011_ZERO_LENGTH, &
|
||||||
UEL3DEB_E012_ZERO_ORIENTATION, UEL3DEB_E013_PARALLEL_ORIENTATION, &
|
UEL3DEB_E012_ZERO_ORIENTATION, UEL3DEB_E013_PARALLEL_ORIENTATION, &
|
||||||
UEL3DEB_E014_LFLAGS2, UEL3DEB_E015_LFLAGS3, UEL3DEB_E016_NDLOAD, &
|
UEL3DEB_E014_LFLAGS2, UEL3DEB_E015_LFLAGS3, UEL3DEB_E016_NDLOAD, &
|
||||||
|
UEL3DEB_E017_LFLAGS1, UEL3DEB_E018_LFLAGS4, &
|
||||||
uel3deb_validate_kernel_inputs
|
uel3deb_validate_kernel_inputs
|
||||||
use uel_3d_euler_beam_abi_adapter, only: uel3deb_abi_static
|
use uel_3d_euler_beam_abi_adapter, only: uel3deb_abi_static
|
||||||
implicit none
|
implicit none
|
||||||
@@ -60,32 +61,37 @@ contains
|
|||||||
end subroutine test_kernel_physical_diagnostics
|
end subroutine test_kernel_physical_diagnostics
|
||||||
|
|
||||||
subroutine test_adapter_shape_and_request_diagnostics()
|
subroutine test_adapter_shape_and_request_diagnostics()
|
||||||
call expect_adapter_status(11, 1, 0, 9, 3, 2, 12, 0, 0, 0, 1, &
|
call expect_adapter_status(11, 1, 1, 9, 3, 2, 12, 0, 0, 1, 0, 0, 1, &
|
||||||
UEL3DEB_E001_NDOFEL, 'NOA-I-SHAPE-001 NDOFEL')
|
UEL3DEB_E001_NDOFEL, 'NOA-I-SHAPE-001 NDOFEL')
|
||||||
call expect_adapter_status(12, 1, 0, 9, 3, 1, 12, 0, 0, 0, 1, &
|
call expect_adapter_status(12, 1, 1, 9, 3, 1, 12, 0, 0, 1, 0, 0, 1, &
|
||||||
UEL3DEB_E002_NNODE, 'NOA-I-SHAPE-001 NNODE')
|
UEL3DEB_E002_NNODE, 'NOA-I-SHAPE-001 NNODE')
|
||||||
call expect_adapter_status(12, 1, 0, 9, 2, 2, 12, 0, 0, 0, 1, &
|
call expect_adapter_status(12, 1, 1, 9, 2, 2, 12, 0, 0, 1, 0, 0, 1, &
|
||||||
UEL3DEB_E003_MCRD, 'NOA-I-SHAPE-001 MCRD')
|
UEL3DEB_E003_MCRD, 'NOA-I-SHAPE-001 MCRD')
|
||||||
call expect_adapter_status(12, 1, 0, 8, 3, 2, 12, 0, 0, 0, 1, &
|
call expect_adapter_status(12, 1, 1, 8, 3, 2, 12, 0, 0, 1, 0, 0, 1, &
|
||||||
UEL3DEB_E004_NPROPS, 'NOA-I-SHAPE-001 NPROPS')
|
UEL3DEB_E004_NPROPS, 'NOA-I-SHAPE-001 NPROPS')
|
||||||
call expect_adapter_status(12, 1, 0, 9, 3, 2, 12, 0, 1, 0, 1, &
|
call expect_adapter_status(12, 1, 1, 9, 3, 2, 12, 0, 1, 1, 0, 0, 1, &
|
||||||
UEL3DEB_E005_NJPROP, 'NOA-I-SHAPE-001 NJPROP')
|
UEL3DEB_E005_NJPROP, 'NOA-I-SHAPE-001 NJPROP')
|
||||||
call expect_adapter_status(12, 1, 1, 9, 3, 2, 12, 0, 0, 0, 1, &
|
call expect_adapter_status(12, 1, 0, 9, 3, 2, 12, 0, 0, 1, 0, 0, 1, &
|
||||||
UEL3DEB_E006_NSVARS, 'NOA-I-SHAPE-001 NSVARS')
|
UEL3DEB_E006_NSVARS, 'NOA-I-SHAPE-001 NSVARS')
|
||||||
call expect_adapter_status(12, 2, 0, 9, 3, 2, 12, 0, 0, 0, 1, &
|
call expect_adapter_status(12, 2, 1, 9, 3, 2, 12, 0, 0, 1, 0, 0, 1, &
|
||||||
UEL3DEB_E007_NRHS, 'NOA-I-SHAPE-001 NRHS')
|
UEL3DEB_E007_NRHS, 'NOA-I-SHAPE-001 NRHS')
|
||||||
call expect_adapter_status(12, 1, 0, 9, 3, 2, 11, 0, 0, 0, 1, &
|
call expect_adapter_status(12, 1, 1, 9, 3, 2, 11, 0, 0, 1, 0, 0, 1, &
|
||||||
UEL3DEB_E008_MLVARX, 'NOA-I-SHAPE-001 MLVARX')
|
UEL3DEB_E008_MLVARX, 'NOA-I-SHAPE-001 MLVARX')
|
||||||
call expect_adapter_status(12, 1, 0, 9, 3, 2, 12, 0, 0, 1, 1, &
|
call expect_adapter_status(12, 1, 1, 9, 3, 2, 12, 0, 0, 3, 0, 0, 1, &
|
||||||
|
UEL3DEB_E017_LFLAGS1, 'NOA-I-LFLAGS-001 LFLAGS1')
|
||||||
|
call expect_adapter_status(12, 1, 1, 9, 3, 2, 12, 0, 0, 1, 1, 0, 1, &
|
||||||
UEL3DEB_E014_LFLAGS2, 'NOA-I-LFLAGS-001 LFLAGS2')
|
UEL3DEB_E014_LFLAGS2, 'NOA-I-LFLAGS-001 LFLAGS2')
|
||||||
call expect_adapter_status(12, 1, 0, 9, 3, 2, 12, 0, 0, 0, 3, &
|
call expect_adapter_status(12, 1, 1, 9, 3, 2, 12, 0, 0, 1, 0, 3, 1, &
|
||||||
UEL3DEB_E015_LFLAGS3, 'NOA-I-LFLAGS-001 LFLAGS3')
|
UEL3DEB_E015_LFLAGS3, 'NOA-I-LFLAGS-001 LFLAGS3')
|
||||||
call expect_adapter_status(12, 1, 0, 9, 3, 2, 12, 1, 0, 0, 1, &
|
call expect_adapter_status(12, 1, 1, 9, 3, 2, 12, 0, 0, 1, 0, 1, 1, &
|
||||||
|
UEL3DEB_E018_LFLAGS4, 'NOA-I-LFLAGS-001 LFLAGS4')
|
||||||
|
call expect_adapter_status(12, 1, 1, 9, 3, 2, 12, 1, 0, 1, 0, 1, 0, &
|
||||||
UEL3DEB_E016_NDLOAD, 'NOA-I-LFLAGS-001 NDLOAD')
|
UEL3DEB_E016_NDLOAD, 'NOA-I-LFLAGS-001 NDLOAD')
|
||||||
end subroutine test_adapter_shape_and_request_diagnostics
|
end subroutine test_adapter_shape_and_request_diagnostics
|
||||||
|
|
||||||
subroutine expect_adapter_status(ndofel, nrhs, nsvars, nprops, mcrd, nnode, &
|
subroutine expect_adapter_status(ndofel, nrhs, nsvars, nprops, mcrd, nnode, &
|
||||||
mlvarx, ndload, njprop, lflag2, lflag3, &
|
mlvarx, ndload, njprop, lflag1, lflag2, &
|
||||||
|
lflag3, lflag4, &
|
||||||
expected_status, message)
|
expected_status, message)
|
||||||
integer, intent(in) :: ndofel
|
integer, intent(in) :: ndofel
|
||||||
integer, intent(in) :: nrhs
|
integer, intent(in) :: nrhs
|
||||||
@@ -96,8 +102,10 @@ contains
|
|||||||
integer, intent(in) :: mlvarx
|
integer, intent(in) :: mlvarx
|
||||||
integer, intent(in) :: ndload
|
integer, intent(in) :: ndload
|
||||||
integer, intent(in) :: njprop
|
integer, intent(in) :: njprop
|
||||||
|
integer, intent(in) :: lflag1
|
||||||
integer, intent(in) :: lflag2
|
integer, intent(in) :: lflag2
|
||||||
integer, intent(in) :: lflag3
|
integer, intent(in) :: lflag3
|
||||||
|
integer, intent(in) :: lflag4
|
||||||
integer, intent(in) :: expected_status
|
integer, intent(in) :: expected_status
|
||||||
character(len=*), intent(in) :: message
|
character(len=*), intent(in) :: message
|
||||||
real(dp) :: rhs(12, 2)
|
real(dp) :: rhs(12, 2)
|
||||||
@@ -118,8 +126,10 @@ contains
|
|||||||
u = 0.0_dp
|
u = 0.0_dp
|
||||||
pnewdt = 1.0_dp
|
pnewdt = 1.0_dp
|
||||||
lflags = 0
|
lflags = 0
|
||||||
|
lflags(1) = lflag1
|
||||||
lflags(2) = lflag2
|
lflags(2) = lflag2
|
||||||
lflags(3) = lflag3
|
lflags(3) = lflag3
|
||||||
|
lflags(4) = lflag4
|
||||||
jprops = 0
|
jprops = 0
|
||||||
|
|
||||||
call uel3deb_abi_static(rhs, amatrx, energy, ndofel, nrhs, nsvars, props, &
|
call uel3deb_abi_static(rhs, amatrx, energy, ndofel, nrhs, nsvars, props, &
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
from scripts.test_uel_3d_euler_beam_uel import Uel3dEulerBeamWrapperContractTests
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["Uel3dEulerBeamWrapperContractTests"]
|
||||||
Reference in New Issue
Block a user