299 lines
12 KiB
Markdown
299 lines
12 KiB
Markdown
# FESA Phase 1 Abaqus Input Subset
|
|
|
|
## 1. Status and scope
|
|
|
|
This document is the normative input contract for the FESA Phase 1 Abaqus
|
|
adapter. FESA accepts only the keywords, parameters, scopes, and data forms
|
|
defined here. It does not implement general Abaqus input syntax, and it never
|
|
silently ignores an unknown keyword or option.
|
|
|
|
Two mutually exclusive organizations are supported:
|
|
|
|
- a flat/orphan mesh whose mesh and set records are in global scope; or
|
|
- one or more `*PART` definitions followed by exactly one `*ASSEMBLY` that
|
|
contains exactly one untransformed `*INSTANCE` of the active Part.
|
|
|
|
Only the active Part is normalized into `Domain`. Names and external labels are
|
|
input identity; generated nonnegative FESA IDs and dense indices are separate.
|
|
FESA performs no unit conversion.
|
|
|
|
`tests/fixtures/abaqus/contract.tsv` is the executable valid/invalid fixture
|
|
matrix for this document. Its expected diagnostic code and line are part of
|
|
the contract. A diagnostic for a bad data row points to that row; a keyword,
|
|
parameter, or scope error points to the keyword row.
|
|
|
|
## 2. Common lexical rules
|
|
|
|
- Input is UTF-8. A UTF-8 BOM is accepted only at the start of the file.
|
|
- Blank lines and lines whose first non-whitespace characters are `**` are
|
|
ignored. A comment or blank line does not end the current keyword record.
|
|
- Keyword names, parameter names, flag parameters, and the enumerated values
|
|
named below are ASCII case-insensitive. Entity names are trimmed and then
|
|
matched exactly.
|
|
- Fields are comma-separated and surrounding ASCII whitespace is ignored.
|
|
- External node and element labels are positive signed 64-bit integers. DOF
|
|
numbers are integers 1 through 6. Real fields must be finite.
|
|
- A flag parameter has no `=` value. A valued parameter must have one nonempty
|
|
value. Duplicate parameters are `abaqus.syntax.duplicate_parameter`.
|
|
- Parameters not listed for a keyword are
|
|
`abaqus.syntax.unsupported_parameter`. Unknown keywords, including
|
|
`*INCLUDE`, are `abaqus.unsupported_keyword`.
|
|
- A non-comment data line without an open data-bearing keyword is
|
|
`abaqus.syntax.data_without_keyword`.
|
|
|
|
## 3. Scope and ordering
|
|
|
|
The parser maintains `global`, `part`, `assembly`, `instance`, and `step`
|
|
scope. `*STEP` is a global child scope: model-data records already opened in
|
|
global scope remain model data, while `*STATIC`, `*CLOAD`, `*RESTART`, and
|
|
`*OUTPUT` belong to the open Step.
|
|
|
|
The accepted ordering is:
|
|
|
|
```text
|
|
optional *HEADING and *PREPRINT
|
|
flat mesh, or one or more *PART blocks and one *ASSEMBLY block
|
|
global materials
|
|
optional global model-data *BOUNDARY
|
|
one *STEP
|
|
one *STATIC
|
|
optional *BOUNDARY and *CLOAD
|
|
optional no-op *RESTART and *OUTPUT
|
|
*END STEP
|
|
```
|
|
|
|
References are resolved after the complete deck is parsed. A material may
|
|
therefore follow the Part that uses it, and a nested set may refer to a set
|
|
declared later in the same scope.
|
|
|
|
## 4. Mesh and hierarchy keywords
|
|
|
|
### 4.1 `*NODE`
|
|
|
|
- Scope: flat global or Part; not Assembly, Instance, or Step.
|
|
- Parameters: none.
|
|
- Data: one or more `label, x, y, z` rows, with exactly four nonempty fields.
|
|
- Semantics: labels are unique in their mesh scope. Reuse in an inactive Part
|
|
is allowed because it is a different Part scope.
|
|
- Diagnostics: `abaqus.syntax.invalid_node_scope`,
|
|
`abaqus.semantic.invalid_node_data`, `abaqus.semantic.duplicate_node_label`.
|
|
|
|
### 4.2 `*ELEMENT`
|
|
|
|
- Scope: flat global or Part.
|
|
- Parameters: required `TYPE=B31`; optional `ELSET=<name>`; no others.
|
|
- Data: one or more `element_label, node_1_label, node_2_label` rows.
|
|
- Semantics: element labels are unique in their mesh scope. Both nodes must
|
|
exist in that scope. `ELSET=` adds every row to the named element set and
|
|
merges with an explicit set of the same name using sorted-unique membership.
|
|
- Diagnostics: `abaqus.syntax.invalid_element_scope`,
|
|
`abaqus.semantic.unsupported_element`,
|
|
`abaqus.semantic.invalid_element_data`,
|
|
`abaqus.semantic.duplicate_element_label`,
|
|
`abaqus.semantic.missing_node`.
|
|
|
|
### 4.3 Part delimiters
|
|
|
|
`*PART` is global-only, requires exactly `NAME=<name>`, and accepts no data.
|
|
Part names are unique. `*END PART` accepts no parameters or data and closes the
|
|
open Part. Nesting or a mismatched delimiter is invalid.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_part_scope`,
|
|
`abaqus.syntax.unexpected_end_part`, `abaqus.syntax.unclosed_part`, and
|
|
`abaqus.semantic.duplicate_part`.
|
|
|
|
### 4.4 Assembly delimiters
|
|
|
|
`*ASSEMBLY` is global-only, requires exactly `NAME=<name>`, and accepts no
|
|
data. Phase 1 accepts exactly one Assembly. `*END ASSEMBLY` has no parameters
|
|
or data and closes the open Assembly.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_assembly_scope`,
|
|
`abaqus.syntax.multiple_assemblies`,
|
|
`abaqus.syntax.unexpected_end_assembly`, and
|
|
`abaqus.syntax.unclosed_assembly`.
|
|
|
|
### 4.5 Instance delimiters
|
|
|
|
`*INSTANCE` is Assembly-only and requires exactly `NAME=<name>, PART=<name>`.
|
|
Phase 1 accepts exactly one Instance. No translation or rotation data and no
|
|
keyword record are allowed inside it. `*END INSTANCE` has no parameters or
|
|
data.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_instance_scope`,
|
|
`abaqus.syntax.instance_local_keyword`,
|
|
`abaqus.syntax.unexpected_end_instance`,
|
|
`abaqus.syntax.unclosed_instance`, `abaqus.semantic.instance_count`,
|
|
`abaqus.semantic.instance_transform`, and `abaqus.semantic.missing_part`.
|
|
A transform diagnostic points to the first transform data row.
|
|
|
|
Flat `*NODE`/`*ELEMENT` records combined with any Part/Assembly organization
|
|
are `abaqus.semantic.mixed_mesh_organization`.
|
|
|
|
## 5. Sets
|
|
|
|
`*NSET` and `*ELSET` are allowed in flat global, Part, or Assembly scope.
|
|
|
|
- Required parameter: respectively `NSET=<name>` or `ELSET=<name>`.
|
|
- Optional flag: `GENERATE`.
|
|
- Assembly scope additionally requires `INSTANCE=<active-instance-name>`.
|
|
`INSTANCE=` is forbidden in flat global and Part scope.
|
|
- Explicit data consists of comma-separated positive labels and/or names of
|
|
sets of the same kind and scope. Empty trailing fields are ignored.
|
|
- `GENERATE` data consists of exactly one `start, end, increment` row. All
|
|
values are positive integers, `start <= end`, and `(end-start)` is divisible
|
|
by `increment`.
|
|
- Repeated declarations of the same set merge. Nested references are resolved
|
|
independent of declaration order, cycles are rejected, and final membership
|
|
is deterministic sorted-unique.
|
|
- An Assembly set lifts active-Part local labels through its named Instance.
|
|
It cannot reference an inactive or unknown Instance.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_set_scope`,
|
|
`abaqus.semantic.invalid_generate`, `abaqus.semantic.set_cycle`,
|
|
`abaqus.semantic.missing_set_member`, and
|
|
`abaqus.semantic.wrong_instance`.
|
|
|
|
## 6. Material and Beam section
|
|
|
|
### 6.1 `*MATERIAL` and `*ELASTIC`
|
|
|
|
`*MATERIAL` is global-only, requires exactly `NAME=<name>`, and has no data.
|
|
Material names are unique. Its `*ELASTIC` child is global model data, has no
|
|
parameters, and has exactly one `young_modulus, poisson_ratio` row. Young's
|
|
modulus is finite and positive; Poisson's ratio is finite and satisfies
|
|
`-1 < nu < 0.5`. Temperature and field dependencies are not supported.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_material_scope`,
|
|
`abaqus.semantic.duplicate_material`,
|
|
`abaqus.semantic.elastic_without_material`,
|
|
`abaqus.semantic.missing_elastic`, and
|
|
`abaqus.semantic.invalid_elastic_data`.
|
|
|
|
### 6.2 `*BEAM GENERAL SECTION`
|
|
|
|
- Scope: flat global or Part.
|
|
- Parameters: required `SECTION=GENERAL`, `ELSET=<name>`, and
|
|
`MATERIAL=<name>`; no others.
|
|
- First data row: exactly `A, I_y, I_yz, I_z, J`. `A`, `I_y`, `I_z`, and `J`
|
|
are finite and positive; `I_yz` must be finite and exactly zero for Phase 1.
|
|
- Second data row: exactly three finite components of the local section-axis
|
|
reference direction. Model validation rejects a zero direction or one
|
|
parallel to an assigned element axis.
|
|
- The material and set may be declared later, but must resolve. Every active
|
|
B31 element has exactly one section assignment.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_section_scope`,
|
|
`abaqus.semantic.unsupported_section`,
|
|
`abaqus.semantic.invalid_section_data`,
|
|
`abaqus.semantic.missing_material`,
|
|
`abaqus.semantic.missing_element_set`,
|
|
`abaqus.semantic.missing_section`, and
|
|
`abaqus.semantic.duplicate_section_assignment`.
|
|
|
|
### 6.3 `*TRANSVERSE SHEAR STIFFNESS`
|
|
|
|
This optional record is in the same flat-global or Part scope as, and must
|
|
immediately follow, the affected `*BEAM GENERAL SECTION`. It has no parameters
|
|
and exactly one `K23, K13, SCF` data row. `K23` and `K13` are finite and
|
|
positive. Phase 1 accepts only numeric `SCF=0`; omitted/default `0.25`, nonzero
|
|
values, and the Abaqus `SCF` label are unsupported.
|
|
|
|
For isotropic `G=E/[2(1+nu)]`, FESA stores
|
|
`A_sy=K23/G` and `A_sz=K13/G` with source `input`. If this keyword is absent,
|
|
the semantic mapper stores `A_sy=A_sz=5A/6`, `SCF=0`, with source
|
|
`phase1_default`.
|
|
|
|
The data order follows the Abaqus 2024
|
|
[*TRANSVERSE SHEAR STIFFNESS* reference](https://docs.software.vt.edu/abaqusv2024/English/SIMACAEKEYRefMap/simakey-r-transverseshearstiffness.htm);
|
|
the restriction to numeric zero SCF and the effective-area mapping are FESA
|
|
Phase 1 decisions.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_transverse_shear_scope`,
|
|
`abaqus.semantic.orphan_transverse_shear`,
|
|
`abaqus.semantic.invalid_transverse_shear_data`, and
|
|
`abaqus.semantic.nonzero_scf`.
|
|
|
|
## 7. Linear static step, BC, and load
|
|
|
|
### 7.1 `*BOUNDARY`
|
|
|
|
`*BOUNDARY` is allowed as global model data before the Step or inside the sole
|
|
Step. It has no parameters. Each row is
|
|
`node-or-nset, first_dof[, last_dof[, value]]`. `last_dof` defaults to
|
|
`first_dof`; value defaults to zero. The inclusive DOF range is 1 through 6.
|
|
Repeated identical prescriptions are deduplicated; differing values for one
|
|
node/DOF are rejected.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_boundary_scope`,
|
|
`abaqus.semantic.invalid_boundary_data`,
|
|
`abaqus.semantic.invalid_dof`, `abaqus.semantic.invalid_dof_range`,
|
|
`abaqus.semantic.missing_node_target`, and
|
|
`abaqus.semantic.conflicting_boundary`.
|
|
|
|
### 7.2 `*CLOAD`
|
|
|
|
`*CLOAD` is Step-only and has no parameters. Each row is exactly
|
|
`node-or-nset, dof, magnitude`; DOF is 1 through 6 and magnitude is finite.
|
|
Loads on the same node/DOF are summed in input order after target resolution.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_cload_scope`,
|
|
`abaqus.semantic.invalid_cload_data`, `abaqus.semantic.invalid_dof`, and
|
|
`abaqus.semantic.missing_node_target`.
|
|
|
|
### 7.3 `*STEP`, `*STATIC`, and `*END STEP`
|
|
|
|
`*STEP` is global-only. Optional parameters are `NAME=<name>` and
|
|
`NLGEOM=NO`; omitted name becomes `Step-1`. Exactly one Step is required.
|
|
`NLGEOM=YES` and every other option are unsupported.
|
|
|
|
Exactly one `*STATIC` occurs inside the Step. It has no parameters and accepts
|
|
either no data row or one row of one through four finite positive values
|
|
`initial_increment[, time_period[, minimum_increment[, maximum_increment]]]`.
|
|
The values are accepted as load-step metadata; Phase 1 performs one linear
|
|
solve.
|
|
|
|
`*END STEP` has no parameters or data and closes the Step.
|
|
|
|
Diagnostics are `abaqus.syntax.invalid_step_scope`,
|
|
`abaqus.syntax.unexpected_end_step`, `abaqus.syntax.unclosed_step`,
|
|
`abaqus.semantic.step_count`, `abaqus.semantic.unsupported_step_option`,
|
|
`abaqus.semantic.missing_static`, and
|
|
`abaqus.semantic.invalid_static_data`.
|
|
|
|
## 8. Recognized no-op directives
|
|
|
|
These records are deliberately recognized and do not create Domain entities:
|
|
|
|
- `*HEADING`: global-only, no parameters, zero or more text data rows.
|
|
- `*PREPRINT`: global-only, optional `ECHO`, `MODEL`, `HISTORY`, and `CONTACT`
|
|
parameters, each with value `YES` or `NO`; no data.
|
|
- `*RESTART`: Step-only, optional `WRITE` flag and optional nonnegative integer
|
|
`FREQUENCY`; no data.
|
|
- `*OUTPUT`: Step-only, exactly one `FIELD` or `HISTORY` flag and optional
|
|
`VARIABLE=PRESELECT`; no data.
|
|
|
|
Diagnostics are the common unsupported-parameter diagnostic plus
|
|
`abaqus.syntax.invalid_heading_scope`,
|
|
`abaqus.syntax.invalid_preprint_scope`,
|
|
`abaqus.syntax.invalid_restart_scope`, and
|
|
`abaqus.syntax.invalid_output_scope`. There is no general no-op or
|
|
ignore-unknown path.
|
|
|
|
## 9. Fixture matrix contract
|
|
|
|
The tab-separated manifest columns are:
|
|
|
|
```text
|
|
case_id, outcome, fixture, expected_stage, expected_code, expected_line,
|
|
node_count, element_count, node_set_count, element_set_count,
|
|
prescribed_dof_count, nodal_load_count, shear_source, shear_area_y,
|
|
shear_area_z, checked_node_set, checked_element_set
|
|
```
|
|
|
|
For a valid case, the public `parse_deck()` and `map_deck_to_domain()` path must
|
|
produce a Domain matching every populated expected field. Set checks use
|
|
`name:local-label,...`. For an invalid case, that same public path must fail
|
|
and contain the exact stage, code, and source line in the manifest. Partial
|
|
decks and test-only semantic construction are not accepted.
|